flink相关源码解读

Flink相关源码解读

一、窗口相关源码解读

在这里插入图片描述

说明:上图是对于窗口的主要分类,在这里着重取分析滑动处理时间窗口的源码分析,其他类型可以照此类推。

功能实现代码:

//该程序主要实现的功能是每隔5s计算一次最近10s内的数据的数量
public class WaterMarkTest1 {
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment();

        environment.getConfig().setAutoWatermarkInterval(10000);
        DataStreamSource<String> streamSource = environment.socketTextStream("node01", 8888);

        //事件类型:
        streamSource
                .map(line -> {
                    String[] split = line.split(",");
                    return Tuple2.of(split[0], 1);
                }, Types.TUPLE(Types.STRING, Types.INT))
                .keyBy(tp -> tp.f0)
                .window(SlidingProcessingTimeWindows.of(Time.seconds(10),Time.seconds(5)))
                .sum(1)
                .print();
        environment.execute();
    }
}
解析步骤:
窗口的生成

进入SlidingProcessingTimeWindows.class类中,在这里插入图片描述

首先找到调用的of()方法:
在这里插入图片描述

由上述方法得到对应三个全局变量的值:
		size=10000-------窗口大小
		slide=5000-------滑动步长
		offset=0---------偏移量

然后找到assignWindows()方法,给方法顾名思义就是用于做窗口创建的,
在这里插入图片描述

接下来逐条解析每句代码:
	timestamp = context.getCurrentProcessingTime();
								——获取当前系统时间
	 List<TimeWindow> windows = new ArrayList<>((int) (size / slide));
	 							——声明一个List用于存储产生的窗口
	 long lastStart = TimeWindow.getWindowStartWithOffset(timestamp, offset, slide);
	 							——主要获取一个窗口的开始时间,在下面会进行详细的解读
	  for (long start = lastStart; start > timestamp - size; start -= slide) {
            windows.add(new TimeWindow(start, start + size));
        }
        						——通过循环的方式创建窗口,下面会列举实例

assignWindows()getWindowStartWithOffset()方法解读:在这里插入图片描述

通过对该代码的解读可以得到,该方法的功能就是返回比指定时间戳小的最大可以被slide滑动步长整除的时间戳。

根据long start = lastStart; start > timestamp - size; start -= slide进行窗口创建实例:

timestampstart-timeend-time
169511452216951145201695114530
169511452216951145151695114525

由上述创建了两个,得到带有时间戳1695114522的事件存在两个窗口中。

接下来寻找assignWindows()在何处被调用使用Ctrl+Atl+H,选择WindowOperator在这里插入图片描述

代码量比较大只分为两部分也就是一个if判断:

  • 在这里插入图片描述

​ 该部分主要功能是如果是会话窗口进行窗口的合并

  • 在这里插入图片描述
else之后的代码是进行窗口创建的代码,代码量比较大只需要看以下两句:
		windowState.setCurrentNamespace(window);
					——该句主要规定了Window如何存放,将windowState的CurrentNamespace更新为当前窗口的state,也就是用一个中间变量进行存储。
        windowState.add(element.getValue());
        			——说明了数据如何存放

深入了解以下上述中窗口数据的存放,进入接口AppendingState的实现类HeapListState中,找到其实现的add()方法:在这里插入图片描述

上述代码中主要实现功能:
		1、从StateTable中获得一个类似Map对象
		2、从这map对象中获得对应窗口的List集合,该集合中存放着对应窗口的数据,namespace就是窗口的标识
		3、如果List集合为空则之间创建一个List集合用于存放窗口中的数据
窗口的触发

概述:Flink中含有Trigger抽象类,该类的主要作用就是进行窗口计算触发的判断。

以下为Trigger含有的方法:

在这里插入图片描述

由上图可以看出每种类型的窗口都存在专属自己的触发器,以onEvent()为例:在这里插入图片描述

其次对于每种触发器返回类型做一个深入了解,通过查看TriggerResult进行了解,在这里插入图片描述

对上述参数进行解释:
	CONTINUE——表示继续等待不触发窗口计算
	FIRE_AND_PURGE——表示触发窗口计算同时删除掉窗口内容
	FIRE——表示触发窗口计算,但不删除窗口内容
	PURGE——表示清除窗口中所有元素并丢弃窗口,不触发窗口计算或者转发任何元素

UE——表示继续等待不触发窗口计算
FIRE_AND_PURGE——表示触发窗口计算同时删除掉窗口内容
FIRE——表示触发窗口计算,但不删除窗口内容
PURGE——表示清除窗口中所有元素并丢弃窗口,不触发窗口计算或者转发任何元素


> 补充:虽然每种类型的窗口都含有对应的默认触发器,但是如果在实际开发中并不符合需求也是可以自定义触发器。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值