在与DataflowRunner和Dataflow服务一起运行时,PubsubIO不会将自定义时间戳属性输出为context.timestamp

时间:2018-10-08 14:56:33

标签: google-cloud-dataflow apache-beam google-cloud-pubsub

我正在处理一个Apache Beam项目,该项目遇到了与自定义时间戳属性有关的Dataflow服务和PubsubIO问题。 Beam SDK的当前版本为 2.7.0

在项目中,我们有2个数据流作业通过PubSub主题和订阅进行通信:

  

第一个管道(将数据下沉到PubSub)

该管道适用于基于基本消息,因此除了GlobalWindows(Beam默认)之外,没有应用任何自定义窗口策略。在此管道的最后,我们将所有已分配了属性映射(包括事件时间戳记(例如,“ published_at”))的邮件沉入(写) 使用PubsubIO.writeMessages()的PubSub主题。

注意:如果我们使用PubsubIO.writeMessages().withTimestampAttribute(),则此方法将告诉PubsubIO.ShardFnPubsubIO.WriteFnPubsubClient 写入/覆盖 下沉管道的处理时间到地图中的此属性

  

第二条管道(从PubSub读取数据)

在第二个管道(读取管道)中,我们尝试使用PubsubIO.readMessagesWithAttributes().withTimestampAttribute("published_at")PubsubIO.readStrings().withTimestampAttribute("published_at")作为源。

  • DirectRunner 一起运行时,一切运行正常。消息 从PubSub订阅中读取并输出到 ProcessContext.timestamp()的下游阶段等于它们的下游阶段 事件时间戳记"published_at"
  • 但是与 DataflowRunner 一起运行时,ProcessContext.timestamp() 始终设置为接近实时 管道的处理时间。我们检查并可以确认那些 时间戳记不是来自PubSub的发布时间。所有数据都是 然后分配给错误的窗口(与其事件域相比) 时间戳记。我们预计后期数据将不会分配 进入无效的窗口。

注意:在打开第二个管道以获取某种历史/后期数据之前,我们已经为Pubsub主题填充了大量数据。

Pubsub messages with invalid context timestamp

  

假定的根本原因

深入研究DataflowRunner的源代码,我们可以看到 Dataflow Service使用完全不同的Pubsub代码(覆盖PubsubIO。在管道的构造时读取)来读取和接收到Pubsub

因此,如果要使用Beam SDK的PubsubIO,则必须使用实验性选项"enable_custom_pubsub_source"。但是到目前为止,还没有运气,因为我们遇到了这个问题https://jira.apache.org/jira/browse/BEAM-5674,还无法测试Beam SDK的Pubsub代码。

  

解决方法

我们的当前解决方法是,为消息分配窗口之后,我们实施了 a DoFn来对照其事件时间戳IntervalWindow 如果窗口无效,那么我们只需放下消息,然后再运行每周或半周的作业即可从历史记录中更正它们。最好有一些丢失的数据,而不是计算不正确的数据。

Messages dropped due to invalid windows

请与我们分享此案的经验。我们知道,从数据流水印管理的角度来看,如果摄取的数据稀疏(加班时间不够密集),则可以说水印将自身调整为当前实时。

我们还认为,由于我们仍然不熟悉Apache Beam和Google的Dataflow,因此对于Dataflow服务维护PubsubUnboundedSource的输出时间戳的方式存在误解。

非常感谢!

1 个答案:

答案 0 :(得分:1)

我找到了解决此问题的方法。在我的下沉管道中,与RFC 3339标准相比,时间戳属性设置的日期格式错误。格式化的日期缺少'Z'字符。我们要么修复了'Z'字符,要么更改为使用自纪元以来的毫秒数。两者都很好。

但是有一件事是,当Dataflow服务无法解析错误的日期格式时,它会发出警告或引发错误,而是占用所有元素的处理时间,因此,它们被分配给错误的event_time窗口。