flink1.12.x watermark 水印、水位线

提出问题

窗口是按照 flink所在服务器的 系统时间 触发计算的,即:系统时间 到达 窗口结束时间,就会开始计算,会导致 迟到数据丢失

提示:窗口时间是左闭右开,即:包含开始时间、不包含结束时间

如上图:

  • 当 系统时间 到达 09:21:20 ,窗口1 开始计算,不会等待迟到的 数据3 和 数据4

  • 当 系统时间 到达 09:21:30 ,窗口2 开始计算,由于 数据3 和 数据4 的事件时间,在 窗口1 范围内,所以 窗口2 计算 不包括 数据3 和 数据4

结论: 由于 数据3 和 数据4 迟到,会被 丢弃

解决

flink 提供 Watermark(水印、水位线)机制,解决上面问题

Watermark 水印、水位线

Watermark 是一个时间戳

作用:窗口 按照 Watermark 触发计算,在 一定程度 上 解决 迟到数据丢失 的问题

计算方式

Watermark = 窗口中的数据的最大事件时间 - 最大允许延迟时间或乱序时间

解释: 最大允许延迟时间或乱序时间 是自定义的

作用: 保证 Watermark 会一直上升(增大),不会下降(减小)

例子

在上面的窗口中,有 2 个数据,其中最大的事件时间是 09:21:15,那么:

Watermark = 09:21:15 - 最大允许延迟时间或乱序时间

例子

又来一个数据,在上面的窗口中,有 3 个数据,其中最大的事件时间是 09:21:15,那么:

Watermark = 09:21:15 - 最大允许延迟时间或乱序时间

触发条件

  1. 窗口中有数据

  2. Watermark >= 窗口结束时间

计算公式变换

由于 Watermark = 窗口中的数据的最大事件时间 - 最大允许延迟时间或乱序时间

所以 触发条件变为:窗口中的数据的最大事件时间 - 最大允许延迟时间或乱序时间 >= 窗口结束时间

例子

迟到数据

如下图:数据3、数据4 应该属于 窗口1,但由于迟到,落在 窗口2 中

触发计算

如上图:设置 watermark,最大允许延迟时间或乱序时间是 5 秒,当收到 数据6 时,其事件时间 为 最大事件时间: 09:21:26

根据公式:Watermark = 窗口中的数据的最大事件时间 - 最大允许延迟时间或乱序时间

计算:Watermark = 09:21:26 - 5秒 = 09:21:21

由于 Watermark (09:21:21) 大于等于 窗口1 的结束时间(09:21:19),所以 触发 窗口1 计算,并且 窗口1 包含 迟到的 数据3 和 数据4,类似下图:

理解

窗口结束时间延长了,触发计算的条件,不在由 窗口结束时间 决定,而是是动态的,由 窗口中的数据的最大事件时间 和 最大允许延迟时间或乱序时间 决定

结论

通过 Watermark 触发计算,在一定程度上,避免漏掉迟到数据

缺点

收到 数据5 时,由于 数据5的事件时间 09:21:26 - 延迟 5 秒 >= 窗口结束时间 09:21:20,会触发 窗口1 计算

由于 数据3 迟到太多,仍然会被 丢弃

总结

  • Watermark 是一个时间戳
  • 计算方法:Watermark = 窗口中的数据的最大事件时间 - 最大允许延迟时间或乱序时间
  • 本质:是让 窗口结束时间延长
  • 作用:解决数据乱序、数据延迟
  • 缺点:数据延迟太多,会被 漏掉

原文出处:/show_1IX21Y5HKYc4.html