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

时间:2017-07-24 17:09:54

标签: 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(.....) }

1 个答案:

答案 0 :(得分:5)

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

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

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

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

所有这些都是正确的。这些都可以作为数据流1.x中的GroupByKey和Apache Beam中的OutputTimeFn的选项。

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

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

出于所有这些原因,我们将默认设置从 min 切换到窗口结束。

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

另一个技术性问题是,用户定义的.withOutputTimeFn(OutputTimeFns.outputAtEndOfWindow())已被移除并被OutputTimeFn枚举取代,因此只有这三个选项,而不是编写自己的完整API。