flink及时流处理

原创
2022/02/13 15:59
阅读数 211

及时流处理是有状态流处理的扩展,时间在计算中起着一定的作用。除此之外,当您进行时间序列分析、基于特定时间段(通常称为窗口)进行聚合、或者在事件发生时间非常重要的情况下进行事件处理时,就会出现这种情况。

Notions of Time: Event Time and Processing Time #

当在流程序中引用时间时(例如定义窗口),可以引用不同的时间概念:

处理时间:处理时间是指执行相应操作的机器的系统时间。

当流程序按处理时间运行时,所有基于时间的操作(如时间窗口)将使用运行相应操作符的机器的系统时钟。每小时的处理时间窗口将包括在系统时钟指示整小时期间到达特定操作员的所有记录。例如,如果应用程序在上午9:15开始运行,第一个小时处理时间窗口将包括在上午9:15到10:00之间处理的事件,下一个窗口将包括在上午10:00到11:00之间处理的事件,以此类推。

处理时间是时间的最简单概念,不需要流和机器之间的协调。它提供了最好的性能和最低的延迟。然而,在分布式和异步环境处理时间不提供决定论,因为它是容易的速度记录到系统中(例如从消息队列),运营商之间流动的速度记录在系统内部,并中断(预定,或以其他方式)。

事件时间:事件时间是每个单独事件在其生产设备上发生的时间。这个时间通常在记录进入Flink之前嵌入到记录中,可以从每个记录中提取事件时间戳。在事件时间中,时间的进展取决于数据,而不是任何墙上的时钟。事件时间程序必须指定如何生成事件时间水印(Event time watermark),这是在事件时间中表示进度的机制。这种水印机制将在下面的章节中进行描述。

在理想的情况下,事件时间处理将产生完全一致和确定的结果,无论事件何时到达,或它们的顺序如何。但是,除非已知事件是按顺序(按时间戳)到达的,否则在等待乱序事件时,事件时间处理会导致一些延迟。由于只能等待一段有限的时间,这就限制了确定性事件时间应用程序的能力。

假设所有数据都已经到达,事件时间操作将按照预期的方式运行,即使处理无序或延迟的事件,或重新处理历史数据,也会产生正确和一致的结果。例如,每小时的事件时间窗口将包含所有记录,这些记录携带的事件时间戳位于该小时内,无论它们到达的顺序如何,或何时被处理。(更多信息请参见后期事件一节。)

请注意,有时当事件时间程序实时处理实时数据时,它们会使用一些处理时间操作,以保证它们及时地进行。

Event Time and Processing Time

Event Time and Watermarks #

注意:Flink从数据流模型实现了许多技术。对于事件时间和水印的一个很好的介绍,请看下面的文章。

泰勒·阿奇道(Tyler Akidau)的《101流》(Streaming 101)
数据流模型论文
支持事件时间的流处理器需要一种方法来度量事件时间的进度。例如,当事件时间超过一小时后,需要通知构建每小时窗口的窗口操作符,以便该操作符可以关闭正在运行的窗口。

事件时间可以独立于处理时间(由墙上的时钟测量)进行。例如,在一个程序中,操作员的当前事件时间可能会稍微滞后于处理时间(考虑到接收事件的延迟),而两者以相同的速度进行。另一方面,另一个流程序可能在几周的时间内只进行几秒钟的处理,通过快速前进通过一些历史数据已经缓冲在Kafka主题(或另一个消息队列)。

Flink中在事件时间内度量进程的机制是水印。水印流作为数据流的一部分,一个时间戳t。一个水印(t)宣称事件时间已达到时间t的流,这意味着不应该有更多的元素从流时间戳t ' < = t(即事件与时间戳或等于水印)。

下图显示了带有(逻辑)时间戳和内联水印的事件流。在本例中,事件是有序的(相对于它们的时间戳而言),这意味着水印只是流中的周期性标记。

A data stream with events (in order) and watermarks

水印对于无序流至关重要,如下图所示,在无序流中事件不是按照时间戳排序的。一般来说,水印是一种声明,表示在流的那个点上,在某个时间戳之前的所有事件都应该已经到达。一旦水印到达操作符,操作符可以将其内部事件时间时钟提前到水印的值。

A data stream with events (out of order) and watermarks

请注意,事件时间由新创建的流元素(或元素)继承,这些元素要么来自产生它们的事件,要么来自触发创建这些元素的水印。

并行流中的水印#
水印在源函数处生成,或直接在源函数之后生成。源函数的每个并行子任务通常独立地生成水印。这些水印定义了特定并行源上的事件时间。

当水印通过流程序时,它们会提前到达Operator的事件时间。每当Operator提前其事件时间时,它会为后续操作符生成一个新的下游水印

有些操作符使用多个输入流;例如,一个union或keyBy(…)或partition(…)函数后面的操作符。这样的Operator的当前事件时间是其输入流事件时间的最小值。当它的输入流更新它们的事件时间时,Operator也会更新。

下图显示了在并行流中流动的事件和水印以及跟踪事件时间的Operator的示例。

Parallel data streams and operators with events and watermarks

Lateness #

有可能某些元素会违反水印条件,这意味着即使水印(t)已经出现,时间戳t' <= t的更多元素也会出现。事实上,在许多真实世界的设置中,某些元素可以任意延迟,这使得不可能指定某个事件时间戳中的所有元素发生的时间。此外,即使延迟可以被限制,但是将水印延迟太多通常是不可取的,因为这会导致对事件时间窗口的评估有太多的延迟。

因此,流程序可能会显式地期望一些后期元素。延迟元素是在系统的事件时间时钟(由水印表示)之后到达的元素,该时间已经超过了延迟元素的时间戳。有关如何处理事件时间窗口中的延迟元素的更多信息,请参见允许的延迟。

窗口#
聚合事件(例如,计数、求和)在流上的工作方式与在批处理中不同。例如,计算流中的所有元素是不可能的,因为流通常是无限的(无界的)。相反,流的聚合(计数、求和等)是由窗口限定的,例如“最近5分钟的计数”或“最近100个元素的总和”。

Windows可以是时间驱动(例如:每30秒)或数据驱动(例如:每100个元素)。一个典型的方法是区分不同类型的窗口,例如滚动窗口(没有重叠)、滑动窗口(有重叠)和会话窗口(被不活动间隙打断)。

Time- and Count Windows

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部