4.Time
4.1、Flink如何处理乱序?
watermark+window机制
window中可以对input进行按照Event Time排序,使得完全按照Event Time发生的顺序去处理数据,以达到处理乱序数据的目的。
如果有多个watermark机制,以最后一个为准
4.2、Flink何时触发window?
1、watermark时间 > Event Time(对于late element太多的数据而言)
或者
1、watermark时间 >= window_end_time(对于out-of-order以及正常的数据而言)
2、在[window_start_time,window_end_time)中有数据存在
输入的数据中,根据自身的 Event Time,将数据划分到不同的 window 中,如果 window 中 有数据,则当 watermark 时间>=Event Time 时,就符合了 window 触发的条件了,最终决定 window 触发,还是由数据本身的 Event Time 所属的 window 中的 window_end_time 决定。
4.3、Flink应该如何处理乱序数据,处理最大乱序时间?
window+waterMark
这个要结合自己的业务以及数据情况去设置。如果maxOutOfOrderness(最大允许乱序时间 )设置的太小,而自身数据发送时由于网络等原因导致乱序或者late太多,那么最终的结果就是会有很多单条的数据在window中被触发,数据的正确性影响太大
对于严重乱序的数据,需要严格统计数据最大延迟时间,才能保证计算的数据准确,延时设置太小会影响数据准确性,延时设置太大不仅影响数据的实时性,更加会加重Flink作业的负担,不是对eventTime要求特别严格的数据,尽量不要采用eventTime方式来处理,会有丢数据的风险。
4.4、多并行度流的watermarks
注意:多并行度的情况下,watermark对齐会取所有channel最小的watermark
4.5、watermarks的生成方式
通常,在接收到source的数据后,应该立刻生成watermark;但是,也可以在source后,应用简单的map或者filter操作后,再生成watermark。
注意:如果指定多次watermark,后面指定的会覆盖前面的值。
生成方式
•With Periodic Watermarks
•周期性的触发watermark的生成和发送,默认是100ms
•每隔N秒自动向流里注入一个WATERMARK 时间间隔由ExecutionConfig.setAutoWatermarkInterval 决定. 每次调用getCurrentWatermark 方法, 如果得到的WATERMARK 不为空并且比之前的大就注入流中
•可以定义一个最大允许乱序的时间,这种比较常用
•实现AssignerWithPeriodicWatermarks接口
class MyWatermarksService extends AssignerWithPeriodicWatermarks[(String, Int, String)] {
var currentMaxTimestamp = 0L
val maxOutOfOrderness = 10000L //最大允许的乱序时间是10s
var a: Watermark = null
val format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
override def getCurrentWatermark: Watermark = {
a = new Watermark(currentMaxTimestamp - maxOutOfOrderness)
a
}
override def extractTimestamp(str: (String, Int, String), l: Long): Long = {
val timestamp = str._3.toLong
currentMaxTimestamp = Math.max(timestamp, currentMaxTimestamp)
timestamp
}
}
With Punctuated Watermarks
•基于某些事件触发watermark的生成和发送
•基于事件向流里注入一个WATERMARK,每一个元素都有机会判断是否生成一个WATERMARK. 如果得到的WATERMARK 不为空并且比之前的大就注入流中
•实现AssignerWithPunctuatedWatermarks接口
4.6、Flink 对late element(延迟数据)的处理方式
1、丢弃(默认的方式)
2、allowedLateness 指定允许数据延迟的时间
第二次(或多次)触发的条件是 watermark < window_end_time + allowedLateness 时间内, 这个窗口有 late 数据到达时。
3、sideOutputLateData 收集迟到的数据