Flink对于延迟数据的解决方法:allowedLateness
当我们对流设置窗口后得到的WindowedStream对象就可以使用allowedLateness方法

该方法传入一个Time值,设置允许的长期延迟(迟到)的时间。
和watermark不同。
未设置allowedLateness(为0),当watermark满足条件,会触发窗口的 执行 + 关闭
当设置了allowedLateness,当watermark满足条件后,只会触发窗口的执行,不会触发窗口关闭。
也就是,watermark满足条件后会正常触发窗口计算,将已有的数据完成计算。
但是,不会关闭窗口。如果在allowedLateness允许的时间内仍有这个窗口的数据进来,那么每进来一条,会和已经计算过的(被watermark触发的)数据一起在计算一次。
示例代码
执行结果

如图,1000 4999 属于窗口 0 ~ 5000的数据
当7999提交的时候,满足了watermark的触发,将0 – 5000这个窗口的数据计算了(未关闭)
输出结果(a, 2)
当输入8999的时候,watermark已经被推到了 5999了,已经超出了0-5000窗口的结束时间
但是当我们提交了a 3000 发现,0-5000这个窗口还在,并且3000和原本的1000 4999联合一起计算了一次
得到(a, 3)的结果
这样证明:
长期延迟数据处理机制,如果设置了时间,watermark只会完成触发窗口计算,而不会关闭窗口
同时,当有新数据进入这个窗口还会和已经计算过的数据放在一起再次计算
当,当前事件时间 – 水印长度 – 允许的长期延迟数据时间 >= 窗口的结束时间的时候, 这个窗口才会关闭

如图,可见,后续又输入了9999, 这个9999导致了0-5000窗口的关闭
所以再次输入a 3500 发现就没有反应了。因为属于它的窗口已经关闭了。
9999 – 3000 – 2000 = 4999 3000是水印长度 2000是允许的长期延迟数据时间
4999 就是0-5000这个窗口的触发点,
总结
水印:短期延迟,达到条件后触发计算并且关闭窗口(触发+关闭同时进行)
水印+allowedLateness :短期延迟+ 等待长期延迟效果,达到水印条件后,会触发窗口计算,但是不关闭窗口。事件时间延迟达到水印+allowedLateness之和后会关闭窗口
