我正在处理一个Apache Beam项目,该项目遇到了与自定义时间戳属性有关的Dataflow服务和PubsubIO问题。 Beam SDK的当前版本为 2.7.0 。
在项目中,我们有2个数据流作业通过PubSub主题和订阅进行通信:
第一个管道(将数据下沉到PubSub)
该管道适用于基于基本消息,因此除了GlobalWindows
(Beam默认)之外,没有应用任何自定义窗口策略。在此管道的最后,我们将所有已分配了属性映射(包括事件时间戳记(例如,“ published_at”))的邮件沉入(写) 使用PubsubIO.writeMessages()
的PubSub主题。
注意:如果我们使用PubsubIO.writeMessages().withTimestampAttribute()
,则此方法将告诉PubsubIO.ShardFn
,PubsubIO.WriteFn
和PubsubClient
写入/覆盖 下沉管道的处理时间到地图中的此属性。
第二条管道(从PubSub读取数据)
在第二个管道(读取管道)中,我们尝试使用PubsubIO.readMessagesWithAttributes().withTimestampAttribute("published_at")
和PubsubIO.readStrings().withTimestampAttribute("published_at")
作为源。
ProcessContext.timestamp()
的下游阶段等于它们的下游阶段
事件时间戳记"published_at"
。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的输出时间戳的方式存在误解。
非常感谢!
答案 0 :(得分:1)
我找到了解决此问题的方法。在我的下沉管道中,与RFC 3339标准相比,时间戳属性设置的日期格式错误。格式化的日期缺少'Z'字符。我们要么修复了'Z'字符,要么更改为使用自纪元以来的毫秒数。两者都很好。
但是有一件事是,当Dataflow服务无法解析错误的日期格式时,它会发出警告或引发错误,而是占用所有元素的处理时间,因此,它们被分配给错误的event_time窗口。