分析&回答
Watermark 介绍
Watermark 本质是时间戳,与业务数据一样无差别地传递下去,目的是衡量事件时间的进度(通知 Flink 触发事件时间相关的操作,例如窗口)。
- Watermark 是一个时间戳, 它表示小于该时间戳的事件都已经到达了。
- Watermark 一般情况在源位置产生(也可以在流图中的其它节点产生), 通过流图节点传播。
- Watermark 也是 StreamElement, 和普通数据一起在算子之间传递。
- Watermark 可以触发窗口计算, 时间戳为 Long.MAX_VALUE 表示算子后续没有任何数据。
Watermark 类型
flink 采用 WatermarkStrategy 设置自定义 Watermark 类型,WatermarkGenerator 是 Watermark 的基类。flink 实现了 Punctuated Watermarks 从事件获取事件的时间戳、Periodic Watermarks 周期获取事件的时间戳。
Watermark 的产生
- Watermark 事件产生 PunctuatedAssigner根据事件属性eventTimestamp生成
- Watermark 周期产生 结合算子 TimestampsAndWatermarksOperator 和 TimePeriodicWatermarkGenerator,分析 Watermark 的产生流程。如下图所示,横轴表示 processing time,圆形表示事件,圆形中的时间 t 表示事件时间,圆形落在横轴表示事件在算子中的处理,其中 Watermark 的产生周期为 60s 和允许延迟时间为 10s。以第一个周期 [0,60) 为例,获取事件中的最大事件时间 max,向下游发送 watermark(最大事件时间 - 允许延迟时间 - 1)。
Watermark 的传递
Watermark 的传递方式是广播,即广播方式发送到下游。Watermark 与业务数据一样,无差别地传递下去。
多并发的场景下
Watermark 是 source task 产生,经过 keyby 分组后触发窗口计算。
- ① Watermark 要单调递增。
- ② 如果算子有多个上游(广播)即输入多个 Watermark(T),则该算子取最小 Watermark 即 min(Watermark(T1), Watermark(T2)) 。
反思&扩展
Flink 中的 Time 有哪几种
Flink中的时间有三种类型,如下图所示:
- Event Time:是事件创建的时间。它通常由事件中的时间戳描述,例如采集的日志数据中,每一条日志都会记录自己的生成时间,Flink通过时间戳分配器访问事件时间戳。
- Ingestion Time:是数据进入Flink的时间。
- Processing Time:是每一个执行基于时间操作的算子的本地系统时间,与机器相关,默认的时间属性就是Processing Time。
对于迟到数据是怎么处理的
Flink中 WaterMark 和 Window 机制解决了流式数据的乱序问题,对于因为延迟而顺序有误的数据,可以根据eventTime进行业务处理,对于延迟的数据Flink也有自己的解决办法,主要的办法是给定一个允许延迟的时间,在该时间范围内仍可以接受处理延迟数据:
- 设置允许延迟的时间是通过allowedLateness(lateness: Time)设置
- 保存延迟数据则是通过sideOutputLateData(outputTag: OutputTag[T])保存
- 获取延迟数据是通过DataStream.getSideOutput(tag: OutputTag[X])获取
喵呜面试助手:一站式解决面试问题,你可以搜索微信小程序 [喵呜面试助手] 或关注 [喵呜刷题] -> 面试助手 免费刷题。如有好的面试知识或技巧期待您的共享!