Apache Beam最近通过StateSpec
和@StateId
注释引入了状态单元格,并在Apache Flink和Google Cloud Dataflow中得到了部分支持。
我的问题是关于状态垃圾收集,在窗口流上使用有状态DoFn的情况下。通常,当窗口到期时(即水印通过窗口的末端),跑步者移除(垃圾收集)状态。但是,请考虑早期触发窗格的情况,并且放弃触发的窗格:
input.apply(Window.<MyElement>into(CalendarWindows.days(1))
.triggering(AfterWatermark.pastEndOfWindow()
.withEarlyFirings(
AfterProcessingTime.pastFirstElementInPane()
.plusDelayOf(Duration.standardMinutes(10))
))
.discardingFiredPanes()
.apply(ParDo.of(new MyStatefulDofn()));
在这种情况下,早期触发的键的状态是否会保留到窗口到期之后?即,同一窗口中的后续窗格是否可以访问早期窗格所写的状态?
答案 0 :(得分:1)
您的触发配置不会影响ParDo
的状态处理进度。这些元素会立即提供给DoFn
而不会有任何缓冲/触发,并且DoFn
会在输出时直接控制。
您控制输出的事实是有状态ParDo
处理和Combine.perKey
由触发器控制的重要区别。这就是为什么有状态ParDo
通常是一个很好的选择,当触发器不足以满足您的用例时。
我在Beam博客的帖子中更详细地比较了状态ParDo
处理与Combine
+触发器:https://beam.apache.org/blog/2017/02/13/stateful-processing.html
现在,如果您的有状态GroupByKey
上游某处有Combine.perKey
或ParDo
,则输入元素将与来自上游的某些触发器相关联。但这并不会影响您的有状态ParDo
的状态是如何管理的。由于状态是跨元素持久存在的,而“窗格”只是一个元素,因此状态会一直保持到窗口完全到期为止。
顺便提一下导致问题的非常好的总结!