Google cloud dataflow 如何在数据流中创建用户定义的计数器?

Google cloud dataflow 如何在数据流中创建用户定义的计数器?,google-cloud-dataflow,Google Cloud Dataflow,如何在DoFns中创建自己的计数器 在我的DoFn中,我希望在处理记录时,每次满足条件时都增加一个计数器。我希望此计数器对所有记录的值求和。您可以使用,计数器的总值将显示在UI中 下面是一个示例,我在一个管道中试验了聚合器,该管道只让numOutputShards工作人员休眠数秒。(开始时的GenFakeInput PTransform只返回大小为numoutShard的平坦PCollection): PCollection输出=p .apply(新的GenFakeInput(options.g

如何在DoFns中创建自己的计数器

在我的DoFn中,我希望在处理记录时,每次满足条件时都增加一个计数器。我希望此计数器对所有记录的值求和。

您可以使用,计数器的总值将显示在UI中

下面是一个示例,我在一个管道中试验了聚合器,该管道只让numOutputShards工作人员休眠数秒。(开始时的GenFakeInput PTransform只返回大小为numoutShard的平坦PCollection):

PCollection输出=p
.apply(新的GenFakeInput(options.getNumOutputShards()))
.apply(ParDo.named(“Sleep”)of(new DoFn(){
专用聚合器tSleepSecs;
专用聚合器tWorkers;
专用聚合器tExecTime;
私人长Starttimillis;
@凌驾
公共无效开始绑定(上下文c){
tSleepSecs=c.createAggregator(“总睡眠(秒)”,new Sum.SumLongFn();
tWorkers=c.createAggregator(“Num Workers”,new Sum.SumIntegerFn());
tExecTime=c.createAggregator(“总时钟(秒)”,new Sum.SumLongFn();
startTimeMillis=System.currentTimeMillis();
}
@凌驾
公共void finishBundle(上下文c){
tExecTime.addValue((System.currentTimeMillis()-startTimeMillis)/1000);
}
@凌驾
公共void processElement(ProcessContext c){
试一试{
LOG.info(“睡眠{}秒。”,sleepSecs);
tSleepSecs.addValue(sleepSecs);
附加值(1);
时间单位。秒。睡眠(睡眠秒);
}捕捉(中断异常e){
LOG.info(“在睡眠期间忽略捕获的中断异常”);
}
c、 输出(c.element());
}}));

聚合器能否聚合来自不同DoFn的值?否。当前聚合器的作用域为单个DoFn。
PCollection<String> output = p
    .apply(new GenFakeInput(options.getNumOutputShards()))
    .apply(ParDo.named("Sleep").of(new DoFn<String, String>() {
         private Aggregator<Long> tSleepSecs;
         private Aggregator<Integer> tWorkers;
         private Aggregator<Long> tExecTime;
         private long startTimeMillis;

         @Override
         public void startBundle(Context c) {
           tSleepSecs = c.createAggregator("Total Slept (sec)", new Sum.SumLongFn());
           tWorkers = c.createAggregator("Num Workers", new Sum.SumIntegerFn());
           tExecTime = c.createAggregator("Total Wallclock (sec)", new Sum.SumLongFn());
           startTimeMillis = System.currentTimeMillis();
         }

         @Override
         public void finishBundle(Context c) {
           tExecTime.addValue((System.currentTimeMillis() - startTimeMillis)/1000);
         }

         @Override
         public void processElement(ProcessContext c) {
           try {
             LOG.info("Sleeping for {} seconds.", sleepSecs);
             tSleepSecs.addValue(sleepSecs);
             tWorkers.addValue(1);
             TimeUnit.SECONDS.sleep(sleepSecs);
           } catch (InterruptedException e) {
             LOG.info("Ignoring caught InterruptedException during sleep.");
           }
           c.output(c.element());
         }}));