PubSub水印没有推进

时间:2018-06-05 08:15:34

标签: google-cloud-dataflow google-cloud-pubsub spotify-scio

我使用Scio编写了一个Apache Beam作业,目的是为输入数据记录生成会话ID,然后在将它们输出到BigQuery之前以某种方式丰富它们。这是代码:

val measurements = sc.customInput("ReadFromPubsub",
  PubsubIO
    .readMessagesWithAttributes()
    .withTimestampAttribute("ts")
    .fromSubscription(subscription)
)

measurements
    .map(extractMeasurement).flatMap {
      case Success(event) =>
        Some(event)
      case Failure(ex) =>
        None
    }
    .timestampBy(_.timestamp)
    .withSessionWindows(sessionGap, WindowOptions(
      trigger = Repeatedly.forever(AfterWatermark.pastEndOfWindow()),
      accumulationMode = AccumulationMode.DISCARDING_FIRED_PANES,
      allowedLateness = Duration.standardDays(1),
      timestampCombiner = TimestampCombiner.END_OF_WINDOW
    ))
    .keyBy(_.clientID)
    .groupByKey
    .toWindowed
    .map(assignSessionID)
    .toSCollection.flatMap(_.results)
    .map(enrich)
    .saveAsTypedBigQuery(output, bigquery.WRITE_APPEND, bigquery.CREATE_NEVER)

我正在使用事件时间戳,这是ts中属性键PubsubMessage的值,作为我的timestamp属性。在窗口化数据之前,这与我在.timestampBy中使用的时间戳完全相同。我期待的是,一旦水印超过sessionGap(默认为30分钟),输出触发器就会触发。

使用Dataflow runner和DirectRunner,即使我模拟时间间隔超过30分钟的数据,触发器也不会触发。在Dataflow UI中,我可以看到水印永远不会根据事件时间戳前进,而只会每隔一分钟前进,就像没有收到数据一样。

我已经验证了实际接收到的数据,因为执行窗口之前的转换。我也用around 10 records per second进行了测试,但也许这还不足以更新水印?我还设置了一个JobTest,在其中我获得了预期的输出,也向我发出了问题,即问题是基于时间戳/水印的。

我确信我错过了文档中的重要内容或在某处犯了一个愚蠢的错误,并希望有人能指出我正确的方向。

2 个答案:

答案 0 :(得分:1)

将消息发布到pubsub时,如何生成写入消息的“ ts”属性的时间戳,以及如何对其进行编码?

如果我没记错的话,时间戳必须按照RFC3339规范进行编码,例如“ 2020-10-02T10:00:00-05:00”之类的内容

您可以尝试的另一种方法是暂时删除“ .withTimestampAttribute(“ ts”)“行,以便自动生成所使用的时间戳。然后验证您的水印是否在前进。如果是这样,则说明时间戳值(例如,可能不是您期望的值)或其编码存在问题。

最后,如果使用云数据流运行器,请查看作业状态页面。那应该向您显示数据水印的当前值。您可以检查它是否符合您的期望。

答案 1 :(得分:0)

您可以尝试将early and late firings添加到AfterWatermark.pastEndofWindows中,以查看水印是否已更新,并检查是否有任何迟到的数据。另外,您还可以找到有关触发器here的文档。