为什么要有 Watermark?
当 flink 以 EventTime模式处理流数据时,它会根据数据里的时间戳来处理基于时间的算子。但是由于网络、分布式等原因,会导致数据乱序的情况。如下图所示:
【资料图】
Flink中的WaterMark
只要使用event time,就必须使用watermark,在上游指定,比如:source、map算子后
基本概念
Watermark的核心本质可以理解成一个延迟触发机制。
我们知道,流处理从事件产生,到流经source,再到operator,中间是有一个过程和时间的,虽然大部分情况下,流到operator的数据都是按照事件产生的时间顺序来的,但是也不排除由于网络、背压等原因,导致乱序的产生,所谓乱序,就是指Flink接收到的事件的先后顺序不是严格按照事件的Event Time顺序排列的。
我们来设想一下下面这个场景:
使用时间窗口来统计10分钟内的用户流量
有一个时间窗口
开始时间为:2017-03-19 10:00:00
结束时间为:2017-03-19 10:10:00
有一个数据,因为网络延迟
事件发生的时间为:2017-03-19 10:10:00
但进入到窗口的时间为:2017-03-19 10:10:02,延迟了2秒中
时间窗口并没有将59这个数据计算进来,导致数据统计不正确
根据窗口计算时间的不同,这个数据都会被遗漏,只是:
如果按照处理时间来计算,这个窗口在系统时间大于2017-03-19 10:10:00的时候就会关闭,延迟进来的这个59会被忽略
如果按照事件时间来计算,这个窗口当进入一条数据,其事件时间大于2017-03-19 10:10:00的时候,会导致窗口关闭,同样因为这个59延迟了,会因为别的正常顺序的数据进入Flink而导致属于它的窗口被提前关闭
也就是:
处理时间窗口,按照当前系统时间来判断进行窗口关闭
事件时间窗口,按照进入数据的事件时间来判断是否关闭窗口,如果进来的一条新数据是下一个窗口的数据,那么会关闭上一个窗口
总结:
watermark是水印,也称水位线。用来测量事件时间的进度。
watermark作为数据流中的一部分在流动,并且携带一个时间戳t。
watermark(t) 表示这个流里面事件时间已经到了时间t,意味着流中不应该存在时间戳t2<=t的数据。
触发窗口等的计算、关闭
单调递增的(时间不能倒退)
用来处理数据乱序的问题
标签: