Java 在调试器中调试apache beam/数据流?

Java 在调试器中调试apache beam/数据流?,java,google-cloud-dataflow,apache-beam,dataflow,Java,Google Cloud Dataflow,Apache Beam,Dataflow,这与这篇文章高度相关-> 我们在生产中有一些类似的代码 @覆盖 公共PDone扩展(PCollectionTuple-in){ .getPipeline().getOptions()中的最终RosterPipelineOptions=(RosterPipelineOptions); 试一试{ final Schema Schema=new Schema.Parser().parse(PractitionerStandardAvroWriter.class.getResourceAsStream(

这与这篇文章高度相关->

我们在生产中有一些类似的代码

@覆盖
公共PDone扩展(PCollectionTuple-in){
.getPipeline().getOptions()中的最终RosterPipelineOptions=(RosterPipelineOptions);
试一试{
final Schema Schema=new Schema.Parser().parse(PractitionerStandardAvroWriter.class.getResourceAsStream(“/standardFormat.avsc”);
最终字符串schematr=new BufferedReader(新的InputStreamReader(PractitionerStandardAvroWriter.class.getResourceAsStream(“/standardFormat.avsc”))
.lines().collect(收集器.连接(“\n”);
最终PCollection validOutputs=in.get(PractitionerStandardOutputConverter.VALID\u OUTPUTS\u标记);
最终PCollection invalidOutputs=in.get(PractitionerStandardOutputConverter.INVALID\u OUTPUTS\u标记);
最终PCollection validRecords=validOutputs.apply(
“将有效的标准输出转换为通用行”,ParDo.of(新的GenericRecordConverter(schemaStr));
最终PCollection invalidRecords=invalidOutput.apply(
“将无效的标准输出转换为泛型行”(new GenericRecordConverter(schemaStr));
有效记录
.setCoder(AvroCoder.of(genericord.class,schema))
.apply(“写入记录”,AvroIO.writeGenericRecords(模式)
.to(options.getValidOutput())
.不带硬度());
最终PCollection invalidRows=invalidRecords
.setCoder(AvroCoder.of(genericord.class,schema))
.apply(“将错误Avro转换为Csv”,(新的AvroToCsvConvertFn(schemaStr,,”)部分);
invalidRows.apply(“将错误记录写入Csv”,
TextIO.write().to(options.getInvalidOutput()).withoutshading());
返回PDone.in(in.getPipeline());
}
捕获(IOE异常){
sleekthrow.sleek(e);返回null;
}
}
但是,当我们在测试中调试它时,我们无法看到bug。这段代码很难一步一步地查看到底发生了什么,因为我认为它是在这段代码之后运行的,以变形数据,而这段代码只是如何处理传入数据的定义。如果我错了,请纠正我

两个问题

  • 这是编写可调试的ApacheBeam/dataflow代码的最佳方法吗?我们可以逐步了解并轻松查看错误所在
  • 有没有其他方法可以轻松地调试它,因为我怀疑在应用这些东西时,“真正的执行”发生在该方法之后
谢谢,
院长

总的来说,就像你的另一个问题一样,我的建议如下:

  • 要逐步完成管道,可以编写一个使用IDE运行的单元测试,它将在DirectRunner中运行。这使您能够轻松地通过管道。这不是在数据流中运行,而是在本地运行——它仍然很有价值
  • 您可以在
    expand
    中设置断点,它将在管道构建时被命中。您可以在DoFn的
    进程
    中设置断点,或者为源设置
    拆分
    读取
    ——这些断点将在管道执行时命中

  • 关于编写可调试管道的建议——在本例中,我的建议是编写可单独测试的可组合转换。您可以使用Beam必须为管道编写测试的各种测试实用程序。见:
  • 一些最有价值的测试工具是
    PAssert
    TestStream
    TestPipeline
    。我建议您查看我共享的页面,看看这些实用程序是否有帮助



    对于您的特定管道,我可能认为您可以将pttransform分成更小的部分,并为每个部分编写简单的单元测试。

    谢谢您的建议。是的,团队中的人说这个->“在这种情况下,我的建议是编写可单独测试的可组合转换”。我唯一的问题是关于过去的项目,我们有大量的bug,所以编写一个单元测试有点困难,直到你知道bug在哪里。我试图优化维护,但数据流似乎在另一个方向上优化,这对支持工程师来说很困难。我确实喜欢process/split/read上的断点,并会尝试使用路径it's To bad dataflow(apache beam)不会像guice那样使用构造函数堆栈跟踪(关于真实问题的假堆栈跟踪,准确地向您展示了它是如何发生的)。这在数据流中会很流畅。