flink-allowedLateness与watermark的区别

1.watermark

Flink对于乱序数据怎么办呢?

方案就是 watermark。

watermark,直译为水位线,就是元素可以迟到多久才去关闭窗口。例如一个窗口是[0-5),,watermark允许最多延迟3s(指的是watermark参数是3s),那么一个6s的事件,它的watermark就应该是3,一个7s的watermark是4,这两个都落在窗口中

在flink流处理的Source中或者处理window之前,都可以通过调用assignTimestampsAndWatermarks来指定如何从消息中获得当前事件时间和获得当前事件的watermark。可以直接扩展几个预定义的类实现。默认watermark是0,也即watermark时间等于事件时间。watermark不是对每一条数据都会生成的,默认配置每200ms生成一次,可以通过env.getConfig().setAutoWatermarkInterval()配置产生间隔。

此外,flink还允许在流处理window后设定allow lateness来指定一个最晚的时间,没有超过这个最晚时间,window还是未销毁,可以触发计算。(默认的lateness也是0)

2.allowedLateness

基于EventTime窗口的流式数据,虽然提供了Watermark机制,却只能一定程度上解决数据的乱序问题,但是对于真实业务场景数据的延迟可能会非常严重,即使通过Watermark也无法等到所有的延迟数据进入窗口再进行处理,Flink默认会将这种迟到的数据做丢弃处理,但是有些时候用户希望即使在数据延迟严重的情况下,仍然能得到正确的计算结果,此时就需要AllowedLateness机制来对迟到的数据进行特殊处理。

在讲解AllowedLateness机制之前这里需要分清楚:

    1.Watermark 主要是为了解决数据乱序到达的问题;通过watermark机制来处理out-of-order的问题,属于第一层防护,属于全局性的防护,通常说的乱序问题的解决办法,就是指这类;

    2.AllowedLateness解决窗口触发后数据迟到后的问题;通过窗口上的allowedLateness机制来处理out-of-order的问题,属于第二层防护,属于特定window operator的防护,late element的问题就是指这类。

3. 那么watermark和allowedLateness区别在哪里呢?

这个主要是配合trigger的行为,默认的EventTimeTrigger,之前的元素是不触发window计算的,在watermark达到window end的时候,会触发一次window计算;之后的每一个迟到的元素进入窗口,都会触发一次window计算。所以watermark是保证大部分元素的时间落在windowend+watermark的区间内,减少window计算的触发次数。如果是其他trigger方式,watermark的意义不大。窗口触发计算时,会将窗口数据传给后续的处理过程处理。

很多地方把概念会搞混:

  1. 事件时间<窗口end+watermark大小,元素落在窗口内
  2. flink返回的watermark时间=事件时间-watermark大小
  3. watermark时间<窗口end,元素落在窗口内

如上所述,EventTimeTrigger等一些默认的trigger,在watermark时间达到window end之前是不会触发的,如果事件有一段时间暂停了没有新元素,或者窗口期很长,则导致一直没有触发计算获得结果,延迟比较大,这时候可以使用ContinuousProcessingTimeTrigger。

对于延迟的数据,也可以定时可以把它揪出来处理。通过对WindowedStream设置sideOutputLateData,之后从WindowedStream处理的结果SingleOutputStreamOperator的getSideOutput(OutputTag)方法得到被丢弃的数据(这个是需要定时任务去处理)

只有所有的线程的最小watermark都满足watermark 时间 >= window_end_time时,触发历史窗才会执行。

posted @ 2021-12-09 19:19  奇葩兔子  阅读(552)  评论(0编辑  收藏  举报