Apache Beam:为什么全局窗口9223371950454775中的聚合值的时间戳?

nok*_*tar 4 google-cloud-dataflow apache-beam

我们从Google Dataflow 1.9迁移到Apache Beam 0.6.应用globalwindow后,我们注意到行为更改为时间戳.在Google Dataflow 1.9中,我们会在窗口化/合并功能后在DoFn中获得正确的时间戳.现在我们为时间戳获得了一些巨大的价值,例如9223371950454775,全局窗口的默认行为是否在Apache Beam版本中发生了变化?

input.apply(name(id, "Assign To Shard"), ParDo.of(new AssignToTest()))
      .apply(name(id, "Window"), Window
          .<KV<Long, ObjectNode >>into(new GlobalWindows())
          .triggering(Repeatedly.forever(
              AfterProcessingTime
                  .pastFirstElementInPane()
                  .plusDelayOf(Duration.standardMinutes(1))))
          .discardingFiredPanes())
      .apply(name(id, "Group By Shard"), GroupByKey.create())
      .appy(.....) }
Run Code Online (Sandbox Code Playgroud)

Ken*_*les 5

TL; DR:当您组合一组带时间戳的值时,您需要为聚合的结果选择时间戳.此输出时间戳有多个好的答案.在Dataflow 1.x中,默认值是输入时间戳的最小值.根据我们在Beam中使用1.x的经验,默认值已更改为窗口的末尾.您可以通过添加.withTimestampCombiner(TimestampCombiner.EARLIEST)Window转换来恢复先前的行为.


我打开包装.让我们使用@符号来配对一个值及其时间戳.只关注一个键,你有时间戳值v1 @ t1,v2 @ t2,...等.我会坚持你的原始例子,GroupByKey即使这也适用于其他组合值的方法.所以值的输出可迭代是 任意顺序的[v1,v2,...].

以下是时间戳的一些可能性:

  • min(t1,t2,...)
  • max(t1,t2,...)
  • 这些元素所在的窗口末尾(忽略输入时间戳)

所有这些都是正确的.这些都可用作OutputTimeFnDataflow 1.x和TimestampCombinerApache Beam中的选项.

时间戳有不同的解释,它们对不同的东西很有用.聚合值的输出时间控制下游水印.因此,选择较早的时间戳会更多地保留下游水印,而后来的时间戳允许它向前移动.

  • min(t1,t2,...)允许您解压缩迭代并重新输出v1 @ t1
  • max(t1,t2,...)准确地模拟聚合值完全可用的逻辑时间.出于实现细节的原因,Max确实往往是最昂贵的.
  • 窗口的结尾:
    • 模拟这个聚合代表窗口的所有数据的事实
    • 很容易理解
    • 允许下游水印尽快前进
    • 非常有效率

由于所有这些原因,我们将默认值从min切换到窗口结束.

在Beam中,您可以通过添加.withTimestampCombiner(TimestampCombiner.EARLIEST)Window转换来恢复先前的行为.在Dataflow 1.x中,您可以通过添加迁移到Beam的默认值.withOutputTimeFn(OutputTimeFns.outputAtEndOfWindow()).

另一个技术性是用户定义OutputTimeFn被删除并由TimestampCombiner枚举替换,因此只有这三个选择,而不是编写自己的整个API.