Flink 之水位线(Watermark)| 青训营笔记

408 阅读2分钟

image.png

这是我参与「第四届青训营 」笔记创作活动的的第6天
[第四届青训营笔记创作活动]


一、什么是Watermark

在Flink中,Watermark是一种衡量Event Time进展的机制,用来处理实时数据中的乱序问题的,通常是水位线和窗口结合使用来实现。

通俗的来说,Watermark 就是系统认为的当前真实的Event Time(事件时间)。Watermark本质上是一个时间戳,且是动态变化的,会根据当前最大事件时间产生。

二、为什么需要 Watermark

从设备生成实时流事件,到 Flink 的 source,再到多个 oparator 处理数据,过程中会受到网络延迟、背压等多种因素影响造成事件的处理时间与事件时间有一定的误差(如下图所示)。在这个过程中可能产生一些数据的乱序到达,在进行窗口处理时,不可能无限期的等待延迟数据到达,当到达特定 Watermark 时,认为在 Watermark 之前的数据已经全部达到(即使后面还有延迟的数据), 可以触发窗口计算,这个机制就是 Watermark(水位线)
image.png

在 DataStream API 中可以通过如下代码产生 Watermark:

WatermarkStrategy
    .<Tuple2<Lone, String>>forBoundedOutOfOrderness(Duration.ofSeconds(20))
    .withTimesstampAssigner((event, timestamp) -> event.f0)

三、如何根据 Watermark 处理迟到数据

虽说 Watermark 表明着早于它的事件不应该再出现,但是在生产环境中,接收到水位线之前的消息是不可避免的,这就是所谓的迟到事件。实际上迟到事件是乱序事件的特例,和一般乱序事件不同的是它们的乱序程度超出了水位线的预计,导致窗口在它们到达之前已经关闭。迟到事件出现时窗口已经关闭并产出了计算结果,因此处理的方法有3种:

  • 直接将迟到事件丢弃
  • 将迟到事件收集起来另外处理
  • 重新激活已经关闭的窗口并重新计算以修正结果

Flink 默认的处理方式是直接将数据丢弃,另外两种方式可以分别通过 Side OutputAllowed Lateness 实现。

  1. Side Output
    Side Output 机制可以将迟到事件单独放入一个数据流分支将其收集起来,以便对其进行特殊处理。

  2. Allowed Lateness
    Allowed Lateness 机制允许用户设置一个允许的最大迟到时长。Flink 会再窗口关闭后一直保存窗口的状态直至超过允许迟到时长,这期间的迟到事件不会被丢弃,而是默认会触发窗口重新计算。