Flink窗口源码分析

本文主要围绕 WindowOperator类的三个方法来具体展开 :
一 . processElement(StreamRecord element) 在记录进入窗口窗子的时候被调用
二 . onEventTime(InternalTimer<K, W> timer) 在更新watermark 时候被调用
三 . onProcessingTime(InternalTimer<K, W> timer) 通过 StreamSource类不断地往下调用,就是只要任务启动了,就一直调用

在看这三个方法的具体实现之前,先了解几个问题
一. 窗口类型
一. 数据如何分配窗口
二. 窗口触发器

窗口类型

如下图,flink 有两种窗口,一种全局窗口,一种时间窗口

时间窗口

成员变量 :两个成员变量,为窗口的开始和结束时间在这里插入图片描述
方法 :在这里插入图片描述
getStart() :获取窗口开始时间
getEnd(): 获取窗口结束时间
maxTimestamp () : 获取仍然属于此窗口的最大时间戳
intersects(TimeWindow other): 判断和其他窗口是否有重合
在这里插入图片描述
cover(TimeWindow other) :返回和其他窗口的并集
mergeWindows(Collection windows, MergingWindowAssigner.MergeCallback c) :合并窗口,例如多个 session合并

全局窗口

是单例的,在不使用时间窗口的前提下,所有数据都数据改窗口。
在这里插入图片描述

Assinger

Assinger类型

对于时间窗口,每个assiner都分为eventTime和processingTime两类

windowAssinger 功能
DynamicSessionWindows 可以根据record中的某个字段动态指定 session 的gap
SessionWindows session 的gap是固定的,不可以动态指定(相比上面的,功能没有那么强大)
SlidingWindows 滑动窗口,指定窗口大小和滑动间隔
TumblingWindows 翻滚窗口,指定窗口大小

在这里插入图片描述
如上图:主要有 DynamicsessionWindowAssigner,ssessionWindowsAssigner,GlobalWindowsAssigner,SlidingWindowsAssigner,TumblingWindowsAssigner。 其中每个Assigner都有evnetTime和processTime两种实现。

sessionWindows都继承了 MergingWindowAssigner,表明该Assigner是可以合并窗口
在这里插入图片描述

接下来说一下三种WindowsAssigner的assignWindows方法,以eventTime举例,同processTime一样,只不过传入的timestamp 不同而已!

TumblingEventTimeWindows

在这里插入图片描述
offset 时区偏移量,size 是窗口大小
assignWindows 返回属于该元素的一个窗口
在这里插入图片描述
计算窗口开始时间如上图,假设窗口当前时间为23,窗口大小为5,offset 为0,则窗口为[20,25],由公示可以看出窗口的开始时间和结束时间一定是 窗口大小的倍数。
所以说,flink 任务开始时的第一个窗口的数据可能是不完整的,好比这个例子,相当于只有第一个窗口只有[23,25]的数据。

SlidingEventTimeWindows

在这里插入图片描述
假设 当前元素时间为 24 ,窗口大小为4,slide为2,那么可以计算出该元素属于[20,24],[22,26],[24,28]这三个窗口 。

EventTimeSessionWindows

在这里插入图片描述
这就很简单啦,开始时间为当前时间,结束时间为当前+session超时时间 。
当然,这不是某个元素最终的窗口大小,因为这个窗口是可以合并的。后面会讲。

Tigger

trigger类型

trigger 作用
ContinuousEventTimeTrigger 在窗口大小范围内,根据event time的固定间隔多次触发。比如一个10s的翻滚窗口,用这个tirgger设置2s的间隔,那么在2s,4s,6s,8s,10s都会触发一次,知道窗口结束。
ContinuousProcessingTimeTrigger 在窗口大小范围内,根据processing time的固定间隔多次触发。比如一个10s的翻滚窗口,用这个tirgger设置2s的间隔,那么在2s,4s,6s,8s,10s都会触发一次,知道窗口结束。
CountTrigger 在窗口大小范围内,根据element 条数多次触发。
DeltaTrigger 多次触发,当前element的某个字段和上次触发的element的某个字段做delta计算,超过threshold就触发。
EventTimeTrigger 一次触发,当watermark大于窗口结束时间就触发
ProcessingTimeTrigger 一次触发,当machine time大于窗口结束时间就触发
PurgingTrigger tirgger warpper,当nester trigger触发是,会清空当前窗口的状态。

其中ContinuousTrigger ,deltaTrigger,purgingTrigger是比较高级的tirgger,可以用来实现一些复杂的场景。
在这里插入图片描述

作用就是判断当前窗口是否触发的一个东西

ProcessingTimeTrigger

public class ProcessingTimeTrigger extends Trigger<Object, TimeWindow> {
   
	private static final long serialVersionUID = 1L;

	private ProcessingTimeTrigger() {
   }
	
	//在元素进入window operator的时候被调用,直接注册一个窗口结束时间的定时器,
	// 通过internalTimerService定时调度,调度的时候调用 本类中onProcessingTime 方法直接触发.
	@Override
	public TriggerResult onElement(Object element, long timestamp, TimeWindow window, TriggerContext ctx) {
   
		ctx.registerProcessingTimeTimer(window.maxTimestamp());
		return TriggerResult.CONTINUE;
	}
	//这个可以忽略
	@Override
	public TriggerResult onEventTime(long time, TimeWindow window, TriggerContext ctx) throws Exception {
   
		return TriggerResult.CONTINUE;
	}
	//通过internalTimerService定时调度,直接fire窗口
	@Override
	public TriggerResult onProcessingTime(long time, TimeWindow window, TriggerContext ctx) {
   
		return TriggerResult.FIRE;
	}

ProcessingTimeTrigger

@PublicEvolving
public class EventTimeTrigger extends Trigger<Object, TimeWindow> {
   
	private static final long serialVersionUID = 1L;

	private EventTimeTrigger() {
   }

	// 在元素进入window operator的时候被调用
	// 如果 延迟数据到达,且数据在最大允许延迟之内,窗口没有被清除,则会触发计算
	// 否则 非延迟数据,则通过internalTimerService定时调度,调度的时候调用 本类中onEventTime 方法直接触发
	@Override
	public TriggerResult onElement(Object element, long timestamp, TimeWindow window, TriggerContext ctx) throws Exception {
   
		if (window.maxTimestamp() <= ctx.getCurrentWatermark()) {
   
			// if the watermark is already past the window fire immediately
			return TriggerResult.FIRE;
		} else {
   
			ctx.registerEventTimeTimer(window.maxTimestamp());
			return TriggerResult.CONTINUE;
		}
	}
	//  Time 也就是waterMarker,等于窗口结束时间则触发,否则不触发
	@Override
	public TriggerResult onEventTime(long time, TimeWindow window, TriggerContext ctx) {
   
		return time
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值