Flink_Trigger_Flink 中的响指

本文深入探讨了Flink中的窗口触发机制,包括Trigger的概念、触发条件及不同类型的Trigger工作原理,如EventtimeTrigger、ContinuousEventTimeTrigger等,并通过实例代码展示了如何实现窗口计算的触发。

在上篇文章中,我详细讨论了 Flink 是如何为 record 分配窗口的。接下来我们就要讨论一下什么时机触发对窗口的计算了。这就像响指的功能,当集齐五个石头后,什么时候毁灭宇宙一半的生命呢?大家都知道了, 还差一个响指。我们今天讨论的触发时机,和响指的功能差不多,在 Flink 中,Flink 的开发者给他起了一个非常形象的名字——Trigger。

在这里插入图片描述请看下面的图片, Trigger 就是手枪的扳机。扳动扳机就能射出子弹,在 Flink 里面,Trigger 类决定了,是否对窗口中的数据进行计算,并将计算结构发到后面的算子。
在这里插入图片描述
比喻说完了,下面进入到正题。

正题

总体流程

有一个类是 Trigger 类,window 该不该触发计算,是由它决定的。它返回一个 TriggerResualt 这样的一个 Enumerate 。 当它的值为 Fire 的时候,就会触发窗口的计算。

想要弄清楚 Trigger 是怎么触发的,就涉及到 WindowOperator 和 Trigger(以 EventTimerTrigger 为例),还有 InternalTimeServerImpl 这几个类的调用关系。

我是看了 Flink 的官方文档,知道有 Trigger 这货的,然后我用 ideal 来看的源码,再加上打断点,终于搞清楚这几个的调用过程。调用的过程如下所示:

在这里插入图片描述
InternalTimeServerImpl 是 Flink 的一个定时器实现,如果调用它的 registerEventTimeTimer,注册一个定时时间(可以比作闹钟),等到了时间,InternalTimeServerImpl 会调用 WindowOperator 的 onElement() 函数,WindowOperator 的 onEventTime 方法中也调用了 Trigger 的 onEventTime() 方法,当 onEventTime() 返回 fire 这种 TriggerResualt 的时候,就会触发窗口的计算。

另外一个调用 trigger 的时间是当有新的元素进入到窗口后,WindowOperator 会调用 trigger.onElement 的方法,当 trigger 返回 fire 类型的 triggerResult 后,就要触发窗口的计算。

总体的代码执行逻辑说完了,接下来,我就要从细节上,结合测试数据来看一下,代码的执行过程。

下面我就来描述一下。我们重点来看一下 EventtimeTrigger里面的逻辑。

流程中的细节

使用一个案例来说明 trigger 的作用:


import org.apache.flink.api.common.ExecutionConfig;
import org.apache.flink.api.common.eventtime.*;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.typeinfo.TypeInformation;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.api.java.tuple.Tuple6;
import org.apache.flink.streaming.api.TimeCharacteristic;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.AssignerWithPeriodicWatermarks;
import org.apache.flink.streaming.api.functions.windowing.WindowFunction;
import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.triggers.Trigger;
import org.apache.flink.streaming.api.windowing.triggers.TriggerResult;
import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
import org.apache.flink.util.Collector;

import javax.annotation.Nullable;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * @className: WaterMarkTest
 * @Description:
 * @Author: wangyifei
 * @Date: 2024/4/7 17:26
 */
public class WaterMarkTest {
   
   
    public static void main(String[] args) throws Exception {
   
   
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
        ExecutionConfig config = env.getConfig();
        // 默认的 autoWatermarkInterval 的时间是 200 ms
//        config.setAutoWatermarkInterval(2000L);
        // 并发度的设置是必须的,如果 assignerTimestampAndWatermark() 返回的 DataStream 的并发度大于后面窗口的并发度,
        // 则 DataStream 总会有一个分区的时间戳为 0 ,到了窗口中是取最小的那个, 就是 0 了,这样的话就不能触发窗口的计算了。
        config.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值