【发布时间】:2020-12-23 18:45:03
【问题描述】:
我看到有很多关于为每个密钥添加水印支持的讨论。但是 flink 是否支持每个分区的水印?
目前 - 然后考虑所有水印(非空闲分区)中的最小值。因此,窗口中最后一个挂起的记录也被卡住了。(使用periodicemit增加水印时)
非常感谢任何有关此的信息!
【问题讨论】:
标签: apache-flink
我看到有很多关于为每个密钥添加水印支持的讨论。但是 flink 是否支持每个分区的水印?
目前 - 然后考虑所有水印(非空闲分区)中的最小值。因此,窗口中最后一个挂起的记录也被卡住了。(使用periodicemit增加水印时)
非常感谢任何有关此的信息!
【问题讨论】:
标签: apache-flink
一些来源,例如FlinkKafkaConsumer,支持每个分区的水印。您可以通过在源上调用assignTimestampsAndWatermarks 来获得此信息,而不是在源生成的流上。
这样做是每个消费者实例跟踪每个分区内的最大时间戳,并将这些最大值中的最小值减去配置的有界无序作为其水印。空闲分区将被忽略,如果您将其配置为这样做。
这不仅会产生更准确的水印,而且如果您的事件在每个分区中是有序的,这也可以利用 WatermarkStrategy.forMonotonousTimestamps() 策略。
更多详情请见Watermark Strategies and the Kafka Connector。
至于为什么最后一个窗口没有被触发,这与水印有关,但与每个分区的水印无关。问题只是窗口是由水印触发的,而水印落后于事件中的时间戳。所以水印永远赶不上最后的事件,也永远无法触发最后一个窗口。
这对于无限制的流式作业来说不是问题,因为它们永远不会停止,也永远不会有最后一个窗口。对于批处理作业来说这不是问题,因为它们知道所有数据。但是对于有限的流式传输作业,您需要做一些事情来解决这个问题。从广义上讲,你必须做的是通知 Flink 输入流已经结束——每当 Flink 源检测到它们已经到达基于事件时间的输入流的末尾时,它们就会发出最后一个值为 MAX_WATERMARK 的水印,这将触发任何打开的窗口。
一种方法是使用KafkaDeserializationSchema 和isEndOfStream 的实现,当作业结束时返回true。
【讨论】: