Triggers
a)概述
Trigger
决定了一个窗口(由 window assigner 定义)何时可以被 window function 处理;每个 WindowAssigner
都有一个默认的 Trigger
,如果默认 trigger 无法满足需要,可以在 trigger(...)
调用自定义的 trigger。
Trigger 接口提供了五个方法来响应不同的事件:
onElement()
方法在每个元素被加入窗口时调用。onEventTime()
方法在注册的 event-time timer 触发时调用。onProcessingTime()
方法在注册的 processing-time timer 触发时调用。onMerge()
方法与有状态的 trigger 相关。该方法会在两个窗口合并时,将窗口对应 trigger 的状态合并,比如使用会话窗口时。clear()
方法处理在对应窗口被移除时所需的逻辑。
注意:
- 前三个方法通过返回
TriggerResult
来决定 trigger 如何应对到达窗口的事件,应对方案有以下几种:CONTINUE
: 什么也不做FIRE
: 触发计算PURGE
: 清空窗口内的元素FIRE_AND_PURGE
: 触发计算,计算结束后清空窗口内的元素
- 上面的任意方法都可以用来注册 processing-time 或 event-time timer。
b)触发(Fire)与清除(Purge)
当 trigger 认定一个窗口可以被计算时,它就会触发,也就是返回 FIRE
或 FIRE_AND_PURGE
;即让窗口算子发送当前窗口计算结果的信号,如果一个窗口指定了 ProcessWindowFunction
,所有的元素都会传给 ProcessWindowFunction
,如果是 ReduceFunction
或 AggregateFunction
,则直接发送聚合的结果。
当 trigger 触发时,它可以返回 FIRE
或 FIRE_AND_PURGE
; FIRE
会保留被触发的窗口中的内容,而 FIRE_AND_PURGE
会删除这些内容, Flink 内置的 trigger 默认使用 FIRE
,不会清除窗口的状态。
Purge 只会移除窗口的内容, 不会移除关于窗口的 meta-information 和 trigger 的状态。
c)WindowAssigner 默认的 Triggers
WindowAssigner
默认的 Trigger
足以应付诸多情况;比如,所有的 event-time window assigner 都默认使用 EventTimeTrigger
。 这个 trigger 会在 watermark 越过窗口结束时间后直接触发。
GlobalWindow
的默认 trigger 是永远不会触发的 NeverTrigger
,在使用 GlobalWindow
时,必须自定义一个 trigger。
当在
trigger()
中指定了一个 trigger 时, 实际上覆盖了当前WindowAssigner
默认的 trigger;如果指定了一个CountTrigger
给TumblingEventTimeWindows
,窗口将不再根据时间触发, 而是根据元素数量触发。
d)内置 Triggers 和自定义 Triggers
Flink 包含一些内置 trigger。
EventTimeTrigger
根据 watermark 测量的 event time 触发。ProcessingTimeTrigger
根据 processing time 触发。CountTrigger
在窗口中的元素超过预设的限制时触发。PurgingTrigger
接收另一个 trigger 并将它转换成一个会清理数据的 trigger。
如果需要实现自定义的 trigger,请查看抽象类 Trigger。
https://github.com/apache/flink/blob/release-1.19//flink-streaming-java/src/main/java/org/apache/flink/streaming/api/windowing/triggers/Trigger.java