flink assign watermark源码分析

水印生成

水印生成的周期

默认的生成周期是200毫秒,我们可以在环境中修改这个时间

val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
    // TODO: 改变水印生成的周期
    env.getConfig.setAutoWatermarkInterval(200L)
  • 1
    在这里插入图片描述

  • 2
    在这里插入图片描述

  • 3
    在这里插入图片描述
    可以在这个类中找到代码 StreamExecutionEnvironment
    我们可以看到ProcessingTime的生成水印的间隔是0
    EventTime和IngestionTime默认生成水印间隔为200ms

public void setStreamTimeCharacteristic(TimeCharacteristic characteristic) {
		this.timeCharacteristic = Preconditions.checkNotNull(characteristic);
		if (characteristic == TimeCharacteristic.ProcessingTime) {
			getConfig().setAutoWatermarkInterval(0);
		} else {
			getConfig().setAutoWatermarkInterval(200);
		}
	}

水印的生成的过程

  • 有周期生成指定延迟的水印
  • 针对每条数据判断条件当条件符合生成指定延迟的生成水印 在这里插入图片描述

AssignerWithPeriodicWatermarks生成水印方式的调用方式

1
在这里插入图片描述

  • 2

在这里插入图片描述

  • 3

在这里插入图片描述
从executionConfi中获取watermarkInterval ,大于0时会注册定时器,ProcessingTime 在未自定义水印生成间隔时,watermarkInterval 为0 所以不会创建水印,eventtime 时默认的水印生成间隔为200毫秒,即使未自定义水印的生成间隔 ,也会按照默认的时间间隔来生成水印。其实对于processtime 来说,生成水印是一种多余的操作,因为processtime 的都是有序的,不会存在跟对于process time的延迟数据。第一次生成水印是生成一个在now + watermarkInterval后会触发定时器,去生成水印,然后再创建定时器,然后就可以一直循环下去。

  • 4

在这里插入图片描述
抽象类,我们看一下他的实现
在这里插入图片描述
SystemProcessingTimeService
在这里插入图片描述
会起一个TriggerTask线程放入timerService线程池中等待调度。
在这里插入图片描述

TriggerTask是一个内部类的run方法会回调TimestampsAndPeriodicWatermarksOperator的onProcessingTime方法
在这里插入图片描述
在这里插入图片描述

这里会先调udf(这里就是我们定义的AssignerWithPeriodicWatermarks生成水印方式)中的getCurrentWatermark获取水印,和当前水印时间判断是否需要发送新的水印,最后再次注册定时器
这样产生了一个循环,就会周期性生成水印了。
在这里插入图片描述

AssignerWithPunctuatedWatermarks生成水印方式的调用方式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
直到这里可以看到处理流中每个元素的方法,先抽取时间戳,再执行是否生成水印的判断逻辑

在这里插入图片描述
这个逻辑 事件id=“sensor_1” 的事件才会生成水印 水印的延迟是1分钟
在这里插入图片描述

单并行度水印

整条流中只有一个水印

多并行的watermark

实际在多并行度执行时,WaterMark会有多个值存在,且是不会自动同步的。
watermark对齐会取所有channel最小的watermark。

假设流程设置并行度为2,两个source,同时调用WaterMark生成代码,不断根据处理元素的Event Time生成WaterMark,流程中会有两种不同步的WaterMark标志流。

如果此时有如下两个元素进入处理流程,并在代码中将WaterMark的timestamp打印出来的话,会是1536137355000和1536137349000两个不一样的WaterMark同时存在系统中。如果windows使用session windows, session gap 为3 seconds,理论上来说,Windows function应该被触发,但是,Windows并不会按照并行度为1时的设想调用apply处理方法,因为Windows总是以小的WaterMark为标准,windows同时收到两个并行source传过来的两个WaterMark标志,以1536137349000为标准,只认为1536137349000 WaterMark是有效的,1536137355000是无效的,因为只有一个并行处理的水印到达了1536137355000,另外一个并行度的水印还没到1536137355000。

分析:如果流程中存在两个 WaterMark时间:1536137349000和1536137355000,窗口endtime时间为1536137349000,窗口会被触发吗(默认的触发规则)?

答案是不一定会,在多并行度的情况下,Windows总是以小的WaterMark时间为标准,所以当前窗口认为时间为1536137349000,所以窗口函数,不会被触发。

那么何时会被触发呢?,当所有并行处理的1536137355000水印都到达之后,窗口函数才会被触发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值