Flink系列:事件Time时间乱序到达处理方法

 

到达时间无序

kafka的数据,不一定按照时间产生的时间到达flink,为了解决这个问题,需要引入Watermark

 

时间到达的3种情况

顺序到达

Flink系列:事件Time时间乱序到达处理方法_第1张图片

乱序到达

Flink系列:事件Time时间乱序到达处理方法_第2张图片

 

并发到达

Flink系列:事件Time时间乱序到达处理方法_第3张图片

 

Watermark

如果指定多个Watermark,后面的将覆盖前面的。

两种方法

 

基于时间周期(推荐)

周期性(默认100ms)生成和发送Watermark,定义一个最大允许乱序时间。

Flink系列:事件Time时间乱序到达处理方法_第4张图片

 

基于特定事件

如果发生特定事件,则生成和发送Watermark

Flink系列:事件Time时间乱序到达处理方法_第5张图片

 

 

使用方法

//指定事件时间类型
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
//指定Watermark
messageStream.filter(event->event.contains("")).assignTimestampsAndWatermarks(new TimeWatermark()) ;
  • 当watermark时间>=Event Time时,就符合了window触发的条件了(Event Time
  • Watermark是一种消息延迟多少的方式。它定义了什么时候不再等待更早的数据(即假设不会再有时间小于水位线的事件到达),这个假设是触发窗口计算的基础,只有水位线越过窗口对应的结束时间,窗口才会关闭和进行计算。

 

举例说明

假如我们设置10s的时间窗口(window),那么0~10s,10~20s都是一个窗口,以0~10s为例,0为start-time,10为end-time。假如有4个数据的event-time分别是8(A),12.5(B),9(C),13.5(D),我们设置Watermarks为当前所有到达数据event-time的最大值减去延迟值3.5秒

当A到达的时候,Watermarks为max{8}-3.5=8-3.5 = 4.5 < 10,不会触发计算
当B到达的时候,Watermarks为max(12.5,8)-3.5=12.5-3.5 = 9 < 10,不会触发计算
当C到达的时候,Watermarks为max(12.5,8,9)-3.5=12.5-3.5 = 9 < 10,不会触发计算
当D到达的时候,Watermarks为max(13.5,12.5,8,9)-3.5=13.5-3.5 = 10 = 10,触发计算
触发计算的时候,会将A,C(因为他们都小于10)都计算进去,其中C是迟到的。

max这个很关键,就是当前窗口内,所有事件的最大事件。

这里的延迟3.5s是我们假设一个数据到达的时候,比他早3.5s的数据肯定也都到达了,这个是需要根据经验推算。假设加入D到达以后有到达了一个E,event-time=6,但是由于0~10的时间窗口已经开始计算了,所以E就丢了。

从这里上面E的丢失说明,水位线也不是万能的,但是如果根据我们自己的生产经验+侧道输出等方案,可以做到数据不丢失。

 


 

扩展

Flink系列:事件Time时间分类(指定事件时间)

Flink系列:事件时间乱序到达处理完整Demo例子

你可能感兴趣的:(Flink)