我想在Flink中创建一个基于EventTime的会话窗口,以便在新消息的事件时间比创建窗口的消息的事件时间长180秒以上时触发。
例如:
t1(0 seconds) : msg1 <-- This is the first message which causes the session-windows to be created
t2(13 seconds) : msg2
t3(39 seconds) : msg3
.
.
.
.
t7(190 seconds) : msg7 <-- The event time (t7) is more than 180 seconds than t1 (t7 - t1 = 190), so the window should be triggered and processed now.
t8(193 seconds) : msg8 <-- This message, and all subsequent messages have to be ignored as this window was processed at t7
我想创建一个触发器,以便通过适当的水印或onEventTime触发器实现上述行为。任何人都可以提供一些示例来实现这一目标吗?
答案 0 :(得分:1)
解决此问题的最佳方法可能是使用ProcessFunction,而不是使用自定义窗口。如您的示例所示,如果事件将按照时间戳顺序进行处理,那么这将非常简单。另一方面,如果您必须处理无序的事件(在使用事件时间数据时很常见),它将有些复杂。 (想象一下,时间为187的msg6在t8之后到达。如果有可能,并且如果这会影响您想要产生的结果,则必须进行处理。)
如果事件按顺序进行,那么逻辑将大致如下所示:
使用AscendingTimestampExtractor作为加水印的基础。
使用Flink状态(也许是ListState)来存储窗口内容。当事件到达时,将其添加到窗口中,并检查自第一个事件以来是否已超过180秒。如果是这样,请处理窗口内容并清除列表。
如果事件可能是乱序的,则使用BoundedOutOfOrdernessTimestampExtractor,直到currentWatermark指示事件时间已经超过窗口开始时间180秒后,才处理窗口的内容(可以使用事件时间计时器为了这)。触发窗口时不要完全清除列表,而只需删除属于要关闭的窗口的元素即可。