大家好,我是雷恩Layne,这是《深入浅出flink》系列的第十篇文章,希望能对您有所收获O(∩_∩)O
Trigger(触发器)决定了什么时候窗口准备就绪了,一旦窗口准备就绪就可以使用WindowFunction(窗口计算操作)进行计算。每一个 WindowAssigner(窗口分配器) 都会有一个默认的Trigger。如果默认的Trigger不满足用户的需求,用户可以自定义Trigger。
每一种窗口分配器对应的默认触发器如下:
现在,就让我们一探Flink Trigger的究竟吧!
Flink中预置的Trigger
窗口的计算触发依赖于窗口触发器,每种类型的窗口都有对应的窗口触发机制,都有一个默认的窗口触发器,触发器的作用就是去控制什么时候来触发计算。flink内部定义多种触发器,每种触发器对应于不同的WindowAssigner。常见的触发器如下:
EventTimeTrigger
:通过对比EventTime和窗口的Endtime确定是否触发窗口计算,如果EventTime大于Window EndTime则触发,否则不触发,窗口将继续等待。ProcessTimeTrigger
:通过对比ProcessTime和窗口EndTme确定是否触发窗口,如果ProcessTime大于EndTime则触发计算,否则窗口继续等待。ContinuousEventTimeTrigger
:根据间隔时间周期性触发窗口或者Window的结束时间小于当前EndTime触发窗口计算。ContinuousProcessingTimeTrigger
:根据间隔时间周期性触发窗口或者Window的结束时间小于当前ProcessTime触发窗口计算。CountTrigger
:根据接入数据量是否超过设定的阙值判断是否触发窗口计算。DeltaTrigger
:根据接入数据计算出来的Delta指标是否超过指定的Threshold去判断是否触发窗口计算。PurgingTrigger
:可以将任意触发器作为参数转换为Purge类型的触发器,计算完成后数据将被清理。NeverTrigger
:任何时候都不触发窗口计算
需要注意的是,在EventTime时间语义下,如果设有Watermark,触发的时间还要再加上Watermark的延迟时长。比如EventTimeTrigger,在设置有Watermark的情况下,只有EventTime加上Watermark的延迟时长 大于 Window EndTime触发,否则不触发,窗口将继续等待。
注意,在EventTime时间语义,一定会有Watermark机制,如果EventTime没有设置Watermark,会报错。ProcessingTime是根据系统时间判断的,没有Watermark机制。
上面也提到了,因为每一个WindowAssigner(窗口分配器) 都会有⼀个默认的Trigger,所以下面两段代码的执行效果完全一样:
代码1:
DataStream<String> dataStream = env.socketTextStream("localhost", 7777);
DataStream<Integer> mapDataStream = dataStream.map(value -> Integer.parseInt(value));
//定义一个大小为10s的滚动时间窗口
AllWindowedStream<Integer, TimeWindow> allWindowedStream = mapDataStream
.windowAll(TumblingProcessingTimeWindows.of(Time.seconds(10)))
//求窗口内的最小值
DataStream<Integer> minDataStream = allWindowedStream.min(0);
minDataStream.print();
代码2:
DataStream<String> dataStream = env.socketTextStream("localhost", 7777);
DataStream<Integer> mapDataStream = dataStream.map(value -> Integer.parseInt(value));
//定义一个大小为10s的滚动时间窗口
AllWindowedStream<Integer, TimeWindow> allWindowedStream = mapData