触发器决定窗口(由窗口分配器形成)何时可以由窗口函数处理。每个WindowAssigner
都有一个默认的触发器。如果默认触发器不满足您的需求,您可以使用trigger(…)
指定一个自定义触发器。
触发器接口有五个方法,允许触发器对不同的事件作出反应:
- 对于添加到窗口中的每个元素,都会调用
onElement()
方法。 onEventTime()
方法在注册的事件时间计时器触发时被调用。onProcessingTime()
方法在注册的处理时间计时器触发时被调用。onMerge()
方法与有状态触发器相关,当它们对应的窗口合并时,合并两个触发器的状态,例如使用会话窗口时。- 最后,
clear()
方法执行删除相应窗口所需的任何操作。
关于上述方法,有两件事需要注意:
- 前三种方法通过返回一个TriggerResult来决定如何处理它们的调用事件。动作可以是以下其中之一:
CONTINUE
: 不做任何事,FIRE
: 触发计算,PURGE
: 清除窗口中的元素FIRE_AND_PURGE
: 触发计算,然后清除窗口中的元素。
- 这些方法中的任何一个都可以用于注册处理时间或事件事件的计时器的未来的动作。
Fire and Purge
一旦触发器确定窗口已准备好进行处理,它就会触发,即返回FIRE或FIRE_AND_PURGE。这是窗口操作符发出当前窗口结果的信号。给定一个带有ProcessWindowFunction的窗口,所有元素都被传递给ProcessWindowFunction(可能在将它们传递给一个驱逐器之后)。带有ReduceFunction或AggregateFunction的Windows会直接发出它们急切聚合的结果。
当触发器触发时,它可以是FIRE或FIRE_AND_PURGE。FIRE保留窗口的内容,FIRE_AND_PURGE则删除它的内容。默认情况下,预实现的触发器只是FIRE,而不清除窗口状态。
清除将简单地删除窗口的内容,并保留关于窗口和触发器状态的任何潜在元信息。
WindowAssigners的默认触发器
WindowAssigner的默认触发器适用于许多用例。例如,所有事件时间窗口分配器都有一个EventTimeTrigger作为默认触发器。一旦水印通过窗口的末端,这个触发器就会触发。
GlobalWindow 的默认触发器是不会触发的 NeverTrigger。因此,在使用 GlobalWindow 时,总是必须定义自定义触发器。
通过使用trigger()指定触发器,您将覆盖WindowAssigner的默认触发器。例如,如果你为TumblingEventTimeWindows指定一个CountTrigger,你将不再根据时间的进展而只根据计数来触发窗口。现在,如果您想同时基于时间和计数做出反应,就必须编写自己的自定义触发器。
内置和自定义触发器
Flink自带几个内置触发器。
- (已经提到过)EventTimeTrigger是基于通过
watermark
测量的事件时间的进展来触发的。 - ProcessingTimeTrigger基于处理时间触发。
- 当窗口中的元素数量超过给定限制时,CountTrigger 将触发。
- PurgingTrigger接受另一个触发器作为参数,并将其转换为一个PurgingTrigger。
如果您需要实现一个自定义触发器,您应该检查抽象的 Trigger 类。请注意,该API仍在发展中,在未来的Flink版本中可能会发生变化。