Flink 时间概念 EventTime 和 Watermark
EventTime 与 WaterMarks
时间在流式计算中起很重要的作用,Flink 提供了3种时间模型:EventTime、ProcessingTime、IngestionTime(1.13 版本已经不再提 IngestionTime 了)。
底层实现上分为2种:Processing Time 与 Event Time,Ingestion Time 本质上也是一种 Processing Time,对于3者的描述(参考下图):
- EventTime —— 是事件创建的时间,即数据产生时自带时间戳。
- IngestionTime —— 是事件进入 Flink 的时间(摄取时间),即进入 source operator 是给定的时间戳。
- ProcessingTime —— 是每一个执行 window 操作的本地时间。
为什么必须处理事件时间?
在大多数情况下,消息进入系统中是无序的(网络、硬件、分布式逻辑都可能影响),并且会有消息延迟到达(例如移动场景中,由于手机无信号,导致一系列的操作消息在手机重新连接信号后发送),如果按照消息进入系统的时间计算,结果会与实时严重不符合。理想情况是 event time 和 processing time 是一致的(发生时间即处理时间),但是现实情况是不一致的,两者存在 skew。因此,支持事件时间的流式处理程序需要一种方法来测量事件时间的进度。例如,有一个按小时构建的窗口,当事件时间超过了一小时的时间范围,需要通知该窗口,以便关闭正在进行的窗口。
什么是 Watermark
Flink 中检测事件时间处理进度的机制就是 Watermark,Watermark 作为数据处理流中的一部分进行传输,并且携带一个时间戳 t
。一个 Watermark(t)
表示流中应该不再有事件时间比 t
小的元素(只是让系统这样认为,并不代表实际情况)。
Watermark 有助于解决乱序问题
下图表示一个顺序的事件流中的 Watermark,w(x) 代表 Watermark 更新值
下图表示一个乱序的事件流中的 Watermark,表示所有事件时间戳小于 Watermark 时间戳的数据都已经处理完了,任何事件大于 Watermark 的元素都不应该再出现(如果出现,系统可以丢弃改消息,或其他处理行为),当然这只是一种推测性的结果(基于多种信息的推测)
延迟记录(Late Elements)
某些记录可能会违反 Watermark 的条件,事件时间小于 t
但是晚于 Watermark(t)
到达。实际运行过程中,事件可能被延迟任意的时间,所以不可能指定一个时间,保证该时间之前的所有事件都被处理了。而且,即使延时时间是有界限的,过多的延迟的时间也是不理想的,会造成时间窗口处理的太多延时。系统允许设置一个可容忍的延迟时间,在距离 t
的时间在可容忍的延迟时间内,可以继续处理数据,否则丢弃。