02-Flink 迟到事件

官网保平安:https://flink.apache.org/

Watermark 是 Flink 处理乱序事件的机制,基于事件时间,通常用来触发窗口计算。Watermark 是 EventTime 下使用 处理进度的标志,仅限于 EventTime 下使用

在使用 EventTime 处理 Stream 数据的时候会遇到数据乱序的问题,流处理从 Event(事件)产生,流经 Source,再到 Operator,这中间需要一定的时间。虽然大部分情况下,传输到 Operator 的数据都是按照事件产生的时间顺序来的,但是也不排除由于网络延迟等原因而导致乱序的产生,特别是使用 Kafka 的时候,多个分区之间的数据无法保证有序。

因此,在进行 Window 计算的时候,不能无限期地等下去,必须要有个机制来保证在特定的时间后触发 Window 进行计算,这个特别的机制就是 Watermark。Watermark 是用于处理乱序事件的。

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

Watermark 可以理解一个特殊的数据,插入到流里面。

Watermark 也可以表示为 Watermaker = 当前计算窗口最大的事件时间 - 允许乱序延迟时间

示例:

  • windows 大小为 10s,窗口:W1[23:12:00~23:12:10],W2[23:12:10~23:12:20]

  • event time:

    • 数据A 23:12:07
    • 数据B 23:12:11
    • 数据C 23:12:08
    • 数据D 23:12:17
    • 数据E 23:12:09
  • 没加入 Watermark,由上到下进入 Flink

    • 数据B 到了之后,W1 就进行了窗口计算,只有 数据A
    • 数据C 迟到了3秒到了之后,由于 W1 已经计算了,所以就丢失了 数据C
  • 加入 Watermark,允许 5 秒乱序延迟,由上到下进入 Flink

    • 数据A 到达:watermark = 12:07 - 5 = 12:02 < 12:10,所以不触发 W1 计算,数据A 属于 W1
    • 数据B 到达:watermark = max{12:11, 12:07} - 5 =12:06 < 12:10,所以不触发 W1 计算,数据B 属于 W2
    • 数据C 到达:watermark = max{12:08, 12:11, 12:07} - 5 = 12:06 <12:10,所以不触发 W1 计算,数据C 属于 W1
    • 数据D 到达:watermark = max{12:17, 12:08, 12:11, 12:07} - 5 = 12:12 > 23:12:10,触发 W1 计算,数据D 属于 W2
    • 数据E 到达:watermark = max{12:09,12:17,12:08,12:11,12:07} -5 =12:12 > 23:12:10,之前已经触发了 W1 计算,所以丢失了 数据E
  • Watermark 注意事项

    • Watermark 设置太小,影响数据准确性。
    • Watermark 设置太大,影响数据实时性。

迟到事件

虽说水位线表明着早于它的事件不应该再出现,但接收到水位线以前的的消息是不可避免的,这就是所谓的迟到事件。

实际上迟到事件是乱序事件的特例,和一般乱序事件不同的是它们的乱序程度超出了水位线的预计,导致窗口在它们到达之前已经关闭。

迟到事件出现时窗口已经关闭并产出了计算结果,因此处理的方法有 3 种:

  • 重新激活已经关闭的窗口并重新计算以修正结果。
  • 将迟到事件收集起来另外处理。
  • 将迟到事件视为错误消息并丢弃。

Flink 默认的处理方式是第 3 种直接丢弃,其他两种方式分别使用 Side Output 和 Allowed Lateness。

  • Side Output 机制可以将延迟事件单独放入一个数据流分支,这会作为 Window 计算结果的副产品,以便用户获取并对其进行特殊处理。
  • Allowed Lateness 机制允许用户设置一个允许的最大迟到时长。
    Flink 会再窗口关闭后一直保存窗口的状态直至超过允许迟到时长,这期间的迟到事件不会被丢弃,而是默认会触发窗口重新计算。
    因为保存窗口状态需要额外内存,并且如果窗口计算使用了 ProcessWindowFunction API 还可能使得每个迟到事件触发一次窗口的全量计算,代价比较大,所以允许迟到时长不宜设得太长,迟到事件也不宜过多,否则应该考虑降低水位线提高的速度或者调整算法。

02-Flink 迟到事件
https://flepeng.github.io/interview-44-数据处理-44-Flink-02-Flink-迟到事件/
作者
Lepeng
发布于
2020年8月8日
许可协议