【Flink-1.17-教程】-【五】Flink 中的时间和窗口(2)时间语义
- 1)Flink 中的时间语义
- 2)时间语义的分类
- 2.1.处理时间(process time)
- 2.2.摄取时间(ingestion time)
- 2.3.事件时间(event time)
- 3)哪种时间语义更重要
- 4)总结
1)Flink 中的时间语义
在流处理中,时间是一个非常核心的概念,是整个系统的基石。比如,我们经常会遇到这样的需求:给定一个时间窗口,比如一个小时,统计时间窗口的内数据指标。那如何界定哪些数据将进入这个窗口呢?在窗口的定义之前,首先需要确定一个应用使用什么样的时间语义。本文将介绍 Flink 的 Event Time
、Processing Time
和 Ingestion Time
三种时间语义。
2)时间语义的分类
2.1.处理时间(process time)
处理时间是指的执行操作的各个设备的时间。对于运行在处理时间上的流程序,所有的基于时间的操作(比如时间窗口)都是使用的设备时钟,比如,一个长度为1个小时的窗口将会包含设备时钟表示的1个小时内所有的数据。
假设应用程序在 9:15am分启动,第1个小时窗口将会包含9:15am到10:00am所有的数据,然后下个窗口是10:00am-11:00am,等等。
处理时间是最简单时间语义,数据流和设备之间不需要做任何的协调,他提供了最好的性能和最低的延迟。但是,在分布式和异步的环境下,处理时间没有办法保证确定性,容易受到数据传递速度的影响:事件的延迟和乱序。
在使用窗口的时候, 如果使用处理时间, 就指定时间分配器为处理时间分配器。
2.2.摄取时间(ingestion time)
摄取时间是指Flink 读取事件时记录的时间。Ingestion Time 是事件到达 Flink Souce 的时间。从Source 到下游各个算子中间可能有很多计算环节,任何一个算子的处理速度快慢可能影响到下游算子的Processing Time。而Ingestion Time定义的是数据流最早进入Flink的时间,因此不会被算子处理速度影响。
Ingestion Time通常是 Event Time 和 Processing Time 之间的一个折中方案。
(1)比起 Event Time,Ingestion Time 可以不需要设置复杂的 Watermark,因此也不需要太多缓存,延迟较低。
(2)比起 Processing Time,Ingestion Time 的时间是 Souce 赋值的,一个事件在整个处理过程从头至尾都使用这个时间,而且后续算子不受前序算子处理速度的影响,计算结果相对准确一些,但计算成本稍高。
2.3.事件时间(event time)
事件时间是指的这个事件发生的时间。在 event 进入Flink之前,通常被嵌入到了 event 中,一般作为这个 event 的时间戳存在。
在事件时间体系中,时间的进度依赖于数据本身,和任何设备的时间无关。事件时间程序必须制定如何产生 Event Time Watermarks(水印)。在事件时间体系中,水印是表示时间进度的标志(作用就相当于现实时间的时钟)。
在理想情况下,不管事件时间何时到达或者他们的到达的顺序如何,事件时间处理将产生完全一致且确定的结果。事件时间处理会在等待无序事件(迟到事件)时产生一定的延迟。由于只能等待有限的时间,因此这限制了确定性事件时间应用程序的可使用性。
假设所有数据都已到达,事件时间操作将按预期方式运行,即使在处理无序或迟到的事件或重新处理历史数据时,也会产生正确且一致的结果。例如,每小时事件时间窗口将包含带有事件时间戳的所有记录,该记录落入该小时,无论它们到达的顺序或处理时间。
3)哪种时间语义更重要
1、从《星球大战》说起
为了更加清晰地说明两种语义的区别,我们来举一个非常经典的例子:电影《星球大战》。
如上图所示,我们会发现,看电影其实就是处理影片中数据的过程,所以影片的上映时间就相当于“处理时间”;而影片的数据就是所描述的故事,它所发生的背景时间就相当于“事件时间”。两种时间语义都有各自的用途,适用于不同的场景。
2、数据处理系统中的时间语义
在实际应用中,事件时间语义会更为常见。一般情况下,业务日志数据中都会记录数据生成的时间戳(timestamp),它就可以作为事件时间的判断基础。在 Flink 中,由于处理时间比较简单,早期版本默认的时间语义是处理时间;而考虑到事件时间在实际应用中更为广泛,从 Flink1.12 版本开始,Flink 已经将事件时间作为默认的时间语义了。
4)总结
1、Event Time
的优势是结果的可预测性,缺点是缓存较大,增加了延迟,且调试和定位问题更复杂。
2、Processing Time
只依赖当前执行机器的系统时钟,不需要依赖 Watermark
,无需缓存。Processing Time
是实现起来非常简单,也是延迟最小的一种时间语义;但是,在分布式和异步的环境下,Processing Time
不能提供确定性,因为它容易受到事件到达系统的速度(例如从消息队列)、事件在系统内操作流动的速度以及中断的影响。
3、Ingestion Time
通常是 Event Time
和 Processing Time
之间的一个折中方案。
4、在 Flink 流处理真实场景中,大部分的业务需求都会使用事件时间语义
,但还是以具体的业务需求择选不同的时间语义。