GCP Dataflow Apache Beam写入输出错误处理

时间:2018-07-02 10:50:34

标签: google-cloud-platform google-cloud-dataflow apache-beam

我需要对数据流进行错误处理,以便使用相同的主键对Spanner进行多次插入。逻辑是在当前消息之后可能会收到较旧的消息,因此我不想覆盖保存的值。因此,我将创建突变作为插入,并在尝试重复插入时抛出错误。

我已经看到了DoFn中try块的几个示例,这些示例写入侧面输出以记录任何错误。这是一个非常好的解决方案,但是我需要对写入不包含DoFn的Spanner的步骤应用错误处理。

spannerBranchTuples2.get(spannerOutput2)
    .apply("Create Spanner Mutation", ParDo.of(createSpannerMutation))                      
    .apply("Write Spanner Records", SpannerIO.write()
        .withInstanceId(options.getSpannerInstanceId())                  
        .withDatabaseId(options.getSpannerDatabaseId())
        .grouped());

我尚未找到任何允许将错误处理应用于此步骤的文档,或者找到了将其重新编写为DoFn的方法。有什么建议如何将错误处理应用于此吗?谢谢

1 个答案:

答案 0 :(得分:2)

有一个有趣的pattern for this in Dataflow documentation

基本上,我们的想法是在将结果发送到写作转换之前先准备一个DoFn。看起来像这样:

final TupleTag<Output> successTag = new TupleTag<>() {};
final TupleTag<Input> deadLetterTag = new TupleTag<>() {};
PCollection<Input> input = /* … */;
PCollectionTuple outputTuple = input.apply(ParDo.of(new DoFn<Input, Output>() {
  @Override
  void processElement(ProcessContext c) {
  try {
    c.output(process(c.element());
  } catch (Exception e) {
    LOG.severe("Failed to process input {} -- adding to dead letter file",
      c.element(), e);
    c.sideOutput(deadLetterTag, c.element());
  }
}).withOutputTags(successTag, TupleTagList.of(deadLetterTag)));

outputTuple.get(deadLetterTag)
  .apply(/* Write to a file or table or anything */);

outputTuple.get(successTag)
  .apply(/* Write to Spanner or any other sink */);

让我知道这是否有用!