状态和输出的原子性

Atomicity of states and output

如果我的 ProcessElement 方法中的代码既修改了一个(或多个)状态变量又输出了一些结果,我在 Dataflow 中是否可以保证此操作的原子性?

让我们用一个代码示例来阐明我的问题(取自 https://beam.apache.org/blog/stateful-processing/ ):

  @ProcessElement
  public void processElement(
      ProcessContext context,
      @StateId("index") ValueState<Integer> index) {
    int current = firstNonNull(index.read(), 0);
    context.output(KV.of(current, context.element()));
    index.write(current+1);
  }

如果Dataflow worker突然死亡,是否存在context.output()已经executed/checkpointed,但“index”状态变量没有相应更新的风险?

我还有一个疑问是: 我知道 ParDo 可以在同一输入记录上执行两次(由于重试或推测执行),并且 Dataflow 通过使用基于附加到每个输出记录的 ID 的重复数据删除来保证输出的“恰好一次”。 但是,对于像上面的“current+1”这样的状态的一些“非幂等”操作,我是否也得到一些“恰好一次”的保证?

Dataflow 保证状态突变和输出以原子方式提交,也就是说,要么两者都生效,要么都不生效。 (具体来说,StartBundle 和 EndBundle 之间的所有状态和输出都是这样捆绑在一起的。)如果需要重试记录,将使用原始状态。