在Google中使用来自云PCollection订阅的流的、无限制的PubSub。我们使用它作为消防水管,只需不断地将事件传递给BigTable。送货的一切都表现得很好。
我们的问题是,我们有下游批处理作业,期望在BigTable交付后从它读取一天的数据。我想利用加窗和触发来实现一个副作用,当水印超过日阈值时,它会将标记行写入bigtable,这表明数据流有理由相信大多数事件已经交付(我们不需要对完整性的有力保证,只需要合理的保证),并且下游处理可以开始。
我们尝试的是将原始事件写成管道中的一个接收器,然后窗口到另一个接收器中,使用窗格中的计时信息。来确定水印是否前进。这种方法的问题在于它再次对原始事件本身进行操作,这是不可取的,因为它会重复编写事件行。我们可以防止这种写入,但是管道中的并行路径仍将在窗口的事件流上运行。
是否有一种有效的方法在水印上附加一个回调排序,这样我们就可以在水印前进时执行一个单独的动作?
发布于 2016-12-15 21:38:06
在事件时间设置计时器并接收回调的一般功能肯定是一个重要的特性请求,它作为梁-27提交,目前正在积极开发中。
但是实际上,您将窗口化到FixedWindows.of(Duration.standardDays(1))中的方法似乎只需要使用DataflowJavaSDK1.x的特性就可以完成您的目标。您可以通过添加触发器AfterPane.elementCountAtLeast(1)来维护“消防水管”行为,而不是分叉管道。它确实会引起GroupByKey的成本,但不会复制任何东西。
完整的管道可能如下所示:
pipeline
// Read your data from Cloud Pubsub and parse to MyValue
.apply(PubsubIO.Read.topic(...).withCoder(MyValueCoder.of())
// You'll need some keys
.apply(WithKeys.<MyKey, MyValue>of(...))
// Window into daily windows, but still output as fast as possible
.apply(Window.into(FixedWindows.of(Duration.standardDays(1)))
.triggering(AfterPane.elementCountAtLeast(1)))
// GroupByKey adds the necessary EARLY / ON_TIME / LATE labeling
.apply(GroupByKey.<MyKey, MyValue>create())
// Convert KV<MyKey, Iterable<MyValue>>
// to KV<ByteString, Iterable<Mutation>>
// where the iterable of mutations has the "end of day" marker if
// it was ON_TIME
.apply(MapElements.via(new MessageToMutationWithEndOfWindow())
// Write it!
.apply(BigTableIO.Write.to(...);如果我漏掉了你用例的一些细节,请对我的回答发表意见。
https://stackoverflow.com/questions/41130406
复制相似问题