这是我参与「第四届青训营 」笔记创作活动的的第6天
[第四届青训营笔记创作活动]
一、什么是Watermark
在Flink中,Watermark是一种衡量Event Time进展的机制,用来处理实时数据中的乱序问题的,通常是水位线和窗口结合使用来实现。
通俗的来说,Watermark 就是系统认为的当前真实的Event Time(事件时间)。Watermark本质上是一个时间戳,且是动态变化的,会根据当前最大事件时间产生。
二、为什么需要 Watermark
从设备生成实时流事件,到 Flink 的 source,再到多个 oparator 处理数据,过程中会受到网络延迟、背压等多种因素影响造成事件的处理时间与事件时间有一定的误差(如下图所示)。在这个过程中可能产生一些数据的乱序到达,在进行窗口处理时,不可能无限期的等待延迟数据到达,当到达特定 Watermark 时,认为在 Watermark 之前的数据已经全部达到(即使后面还有延迟的数据), 可以触发窗口计算,这个机制就是 Watermark(水位线)。
在 DataStream API 中可以通过如下代码产生 Watermark:
WatermarkStrategy
.<Tuple2<Lone, String>>forBoundedOutOfOrderness(Duration.ofSeconds(20))
.withTimesstampAssigner((event, timestamp) -> event.f0)
三、如何根据 Watermark 处理迟到数据
虽说 Watermark 表明着早于它的事件不应该再出现,但是在生产环境中,接收到水位线之前的消息是不可避免的,这就是所谓的迟到事件。实际上迟到事件是乱序事件的特例,和一般乱序事件不同的是它们的乱序程度超出了水位线的预计,导致窗口在它们到达之前已经关闭。迟到事件出现时窗口已经关闭并产出了计算结果,因此处理的方法有3种:
- 直接将迟到事件丢弃
- 将迟到事件收集起来另外处理
- 重新激活已经关闭的窗口并重新计算以修正结果
Flink 默认的处理方式是直接将数据丢弃,另外两种方式可以分别通过 Side Output 和 Allowed Lateness 实现。
-
Side Output
Side Output 机制可以将迟到事件单独放入一个数据流分支将其收集起来,以便对其进行特殊处理。 -
Allowed Lateness
Allowed Lateness 机制允许用户设置一个允许的最大迟到时长。Flink 会再窗口关闭后一直保存窗口的状态直至超过允许迟到时长,这期间的迟到事件不会被丢弃,而是默认会触发窗口重新计算。