Google cloud dataflow 有状态ParDo不在数据流运行程序上工作
基于Javadocs和上的博客文章,我尝试使用一个简单的重复数据消除示例,使用2.0.0-beta-2SDK从GCS读取一个文件(包含一个JSON列表,每个JSON都有一个用户id字段),然后通过管道运行,如下所述 输入数据包含约146K个事件,其中只有50个事件是唯一的。整个输入大约为50MB,与2分钟的固定窗口相比,可以在相当短的时间内处理。我只是在那里放置了一个窗口,以确保在不使用GlobalWindow的情况下保持每键每窗口语义。我通过3个并行阶段运行窗口化数据,以比较结果,下面将对每个阶段进行解释Google cloud dataflow 有状态ParDo不在数据流运行程序上工作,google-cloud-dataflow,dataflow,apache-beam,Google Cloud Dataflow,Dataflow,Apache Beam,基于Javadocs和上的博客文章,我尝试使用一个简单的重复数据消除示例,使用2.0.0-beta-2SDK从GCS读取一个文件(包含一个JSON列表,每个JSON都有一个用户id字段),然后通过管道运行,如下所述 输入数据包含约146K个事件,其中只有50个事件是唯一的。整个输入大约为50MB,与2分钟的固定窗口相比,可以在相当短的时间内处理。我只是在那里放置了一个窗口,以确保在不使用GlobalWindow的情况下保持每键每窗口语义。我通过3个并行阶段运行窗口化数据,以比较结果,下面将对每个
公共类StatefulParDoSample{
私有静态记录器Logger=LoggerFactory.getLogger(StatefulParDoSample.class.getName());
静态类StatefulDoFn扩展了DoFn{
final Aggregator processedElements=createAggregator(“processed”,Sum.ofLongs());
final Aggregator skippedElements=createAggregator(“skipped”,Sum.ofLongs());
@StateId(“keyTracker”)
私有最终状态规范keyTrackerSpec=
StateSpecs.value(VarIntCoder.of());
@过程元素
公共无效处理元素(
ProcessContext上下文,
@StateId(“keyTracker”)值State keyTracker){
已处理元素。添加值(1l);
最后一个字符串userId=context.element().getKey();
int wasSeen=firstNonNull(keyTracker.read(),0);
如果(wasSeen==0){
keyTracker.write(1);
context.output(context.element().getValue());
}否则{
keyTracker.write(wasSeen+1);
跳过元素。添加值(1l);
}
}
}
公共静态void main(字符串[]args){
DataflowPipelineOptions pipelineOptions=pipelineOptions工厂.create().as(DataflowPipelineOptions.class);
setRunner(DataflowRunner.class);
pipelineOptions.setProject(“项目名称”);
管道选项。设置标记位置(GCS\U标记位置);
pipelineOptions.setStreaming(假);
pipelineOptions.setAppName(“重复数据消除程序”);
Pipeline p=Pipeline.create(pipelineOptions);
最终ObjectMapper映射器=新ObjectMapper();
PCollection键事件=
P
.apply(TextIO.Read.from(GCS_样本_输入_文件_路径))
.apply(带键)of(新的SerializableFunction(){
@凌驾
公共字符串应用(字符串输入){
试一试{
映射事件JSON=
readValue(输入,Map.class);
return(String)eventJson.get(“user_id”);
}捕获(例外e){
}
返回“”;
}
}))
.申请(
开窗(
固定窗口(持续时间标准分钟(2))
)
);
关键事件
.apply(ParDo.of(new StatefulDoFn()))
.apply(TextIO.Write.to(GCS_样本_输出_文件_路径).withNumShards(1));
关键事件
.apply(value.create())
.apply(TextIO.Write.to(GCS_SAMPLE_COPY_FILE_PATH).withNumShards(1));
关键事件
.apply(Combine.perKey(新的SerializableFunction()){
@凌驾
公共字符串应用(Iterable输入){
return!input.iterator().hasNext()?“empty”:input.iterator().next();
}
}))
.apply(value.create())
.apply(TextIO.Write.to(GCS_SAMPLE_COMBINE_FILE_PATH).withNumShards(1));
PipelineResult=p.run();
result.waitUntilFinish();
}
}
这是批处理模式下数据流服务中的一个错误,在即将发布的0.6.0 Beam版本中修复(如果您跟踪前沿,则修复为HEAD)
谢谢你引起我的注意!作为参考,或者如果出现任何其他问题,这是由跟踪的。这是批处理模式下数据流服务中的一个错误,在即将发布的0.6.0 Beam版本中修复(如果跟踪前沿,则为HEAD)
谢谢你引起我的注意!作为参考,或者如果出现任何其他问题,我将对此进行跟踪。我将查看一下。我已经更新了我的答案-这在HEAD和0.6.0版本中以批处理模式工作。我将查看一下。我已经更新了我的答案-这在HEAD和0.6.0版本中以批处理模式工作。因此,你是说这可以在流模式下正常工作吗?我这样问是因为我最终会在流模式下运行管道-因此,这可能不是一个拦截器,如果是这样的话。是的,它应该在流模式下工作。我专门在流模式下运行了您的示例代码作为测试,并获得了成功。谢谢