Flink Watermark机制
请解释Flink中Watermark(水位线)的概念、作用以及如何处理乱序事件。
回答
我还是少年
Watermark定义: 一种时间进度指标,表示系统认为在该时间戳之前的所有事件已经到达(或应该不再期望更晚的事件)。
为什么要Watermark:
- 数据到达存在乱序(Out-of-Order)和延迟(Late)
- 需要确定何时触发窗口计算——不能永远等待所有数据
- Watermark是**权衡完整性(Completeness)和延迟(Latency)**的机制
Watermark工作原理:
时间轴: 1 2 3 4 5 6 7 8 9 10
事件: [A] [B] [C] [D] [E] [F] [G] [H]
Watermark: 3 5 8 10
(Watermark=3时,所有≤3的事件都已到达)
Watermark生成方式:
1. 周期性Watermark(Periodic):
// 每100ms生成一次Watermark
env.getConfig().setAutoWatermarkInterval(100);
// 允许最大乱序时间为5秒
watermarkStrategy = WatermarkStrategy
.<Event>forBoundedOutOfOrderness(Duration.ofSeconds(5))
.withTimestampAssigner((event, timestamp) -> event.timestamp);
2. 断点式Watermark(Punctuated):
- 当遇到特定标记事件时生成,适合有明确结束信号的场景
窗口触发时机:
- 当Watermark ≥ 窗口结束时间 时触发窗口计算
- 如:[10:00:00, 10:00:10)的窗口,在水位线≥10:00:10时触发
处理延迟数据:
- Allowed Lateness: 设置允许延迟时间,延迟数据仍然更新窗口(但需要再次触发)
- Side Output: 无法处理的超迟数据输出到侧输出流(Side Output)
- 丢弃(默认): 舍弃超时的数据
window(TumblingEventTimeWindows.of(Time.seconds(10)))
.allowedLateness(Time.seconds(5))
.sideOutputLateData(lateOutputTag)