
首先说一下时间语义,有三种对时间的定义:
Event Time:事件时间,一般是在数据中,我们指定某个字段为我们的事件时间字段
Ingestion Time:到达时间,指的是数据打到Flink那一刻的时间
Processing Time:执行操作算子的本地系统时间,跟机器相关
在流式处理上,我们更多的是关注事件时间,在新版的datastream中,已经默认使用EventTime作为时间语义了,但是在某些场景下,我们可以根据需求调整
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// 从调用时刻开始给env创建的每一个stream追加时间特征
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
Watermark
水位线,也可以称为水印,这是在事件中处理延时数据的一种方案
(可以参考一下https://blog.csdn.net/lmalds/article/details/52704170)
我们通过source获取数据的时候,大部分情况下都是按照时间顺序的,但是很难保证所有数据,其中有很复杂的情况,比如网络、传输、系统写入延迟、分布式等等


一般来说water需要结合window来实现,在数据中表示”timestamp小于watermark的数据都已经到达了“,所以window的关闭也由watermark来触发
数据达到时我们设置一个延时时长为t,然后每次校验达到的数据中最大的maxEventTime,如果eventTime小于maxEventTime - t 那么说明所有数据已达到了,如果有窗口的停止时间等于maxEventTime - t,那么这个窗口就会被触发计算
watermark = maxEventTime - 延时时间t
watermark可以理解为把原本的窗口标准稍微放宽了一点。(比如原本5s,设置延迟时间=2s,那么实际等到7s的数据到达时,才认为是[0,5)的桶需要关闭了,Watermark是基于数据携带的时间戳生成的,一旦Watermark比当前未触发的窗口的停止时间要晚,那么就会触发相应窗口的执行,值得注意的就是,由于event time是由数据携带的,因此,如果运行过程中无法获取新的数据,那么没有被触发的窗口将永远都不被触发,所以在使用的时候必须注意