Beam 中的状态处理 - 状态是否在 window 窗格之间共享?

Stateful processing in Beam - is state shared across window panes?

Apache Beam 最近通过 StateSpec@StateId 注释引入了状态单元,部分支持 Apache Flink 和 Google Cloud Dataflow。

我的问题是关于状态垃圾回收的,在 windowed 流上使用有状态 DoFn 的情况下。通常,当 window 过期(即水印通过 window 的末尾)时,运行器会删除状态(收集垃圾)。然而,考虑 window 个窗格被提前触发的情况,并且被触发的窗格被丢弃:

input.apply(Window.<MyElement>into(CalendarWindows.days(1))
  .triggering(AfterWatermark.pastEndOfWindow()
  .withEarlyFirings(
    AfterProcessingTime.pastFirstElementInPane()
      .plusDelayOf(Duration.standardMinutes(10))
  ))
  .discardingFiredPanes()
  .apply(ParDo.of(new MyStatefulDofn()));

在这种情况下,提前触发的键的状态是否会一直保持到 window 过期之后?即,同一 window 中的后续窗格是否可以访问早期窗格写入的状态?

您的触发配置不会影响 ParDo 的状态处理方式。这些元素会立即提供给您的 DoFn 而无需任何 buffering/triggering 并且您的 DoFn 直接控制何时发生输出。

您可以控制输出这一事实是有状态 ParDo 处理与由触发器控制的 Combine.perKey 之间的一个重要区别。这就是为什么当触发器对于您的用例来说不够丰富时,有状态 ParDo 通常是一个不错的选择。

我在我的 Beam 博客 post 中更详细地比较了有状态 ParDo 处理与 Combine + 触发器:https://beam.apache.org/blog/2017/02/13/stateful-processing.html

现在,如果有状态 ParDo 上游某处存在 GroupByKeyCombine.perKey,则输入元素将与上游触发的某些触发器相关联。但这不会影响有状态 ParDo 的状态管理方式。由于状态跨元素持久存在,并且 "pane" 只是一个元素,因此状态会一直保持到 window 完全过期。

顺便提一下,关于您的问题的总结非常好!