在使用EventTime处理Stream数据的时候会遇到数据乱序的问题,流处理从Event(事件)产生,流经Source,再到Operator,这中间需要一定的时间。虽然大部分情况下,传输到Operator的数据都是按照事件产生的时间顺序来的,但是也不排除由于网络延迟等原因而导致乱序的产生,特别是使用kafka的时候,多个分区之间的数据无法保证有序因此,在进行window计算的时候,不能无限期的等下去,必须要有个机制来保证特定的时间后,必须出发Window进行计算,这个特别的机制就是Watermark(水位线)。

  

  WaterMark原理

  在Flink的窗口处理过程中,如果确定全部数据到达,就可以对Window的所有数据做窗口计算操作(如汇总、分组等),如果数据没有全部到达,则继续等待该窗口中的数据全部到达才开始处理。这种情况下就需要用到水位线(WaterMark)机制,它能够衡量数据处理进度(表达数据到达的完整性),保证事件数据(全部)到达Flink系统,或者在乱序及延迟到达时,也能够像预期一样计算出正确并且连续的结果。当任何Event进入到Flink系统时,会根据当前最大事件时间产生WaterMark时间戳。

  WaterMark可以理解为一种延迟触发机制,我们可以设置WaterMark的延时时长t,每次系统会校验已经到达的数据中最大的maxEventTime,然后认定eventTime小于maxEventTime-t的所有数据都已经到达,如果有窗口的停止时间等于maxEventTime-t,那么这个窗口被触发执行。

  

flink配置Java Agent flink配置文件禁用水位线_流处理

 

   当Flink接收到数据时,会按照一定的规则去生成WaterMark,这条WaterMark就等于当前所有到达数据中的maxEventTime - 延迟时长,也就是说,WaterMark是由数据携带的,一旦数据携带的WaterMark比当前未触发的窗口的停止时间要晚,那么就会触发相应窗口的执行。由于WaterMark是由数据携带的,因此,如果运行过程中无法获取新的数据,那么没有被触发的窗口将永远都不会被触发。