Flink Concept Timely Stream Processing -Flink概念及时流处理
翻译来源- Concept Timely Stream Processing
介绍
及时的流处理是有状态流处理的扩展,在计算中时间扮演一些角色。此外,当一个事件发生,当您进行时间序列分析时,基于一定的周期(通常称为窗口)进行汇总时,或者做事件处理时,时间确实是重要的。
在以下各节中,我们将重点介绍在使用及时的Flink应用程序时应考虑的一些问题。
时间概念:事件时间和处理时间
在流式程序中引用时间(例如定义窗口)时,可以引用不同的时间概念:
- 处理时间:处理时间是指执行相应操作的机器的系统时间。
当流式程序按处理时间运行时,所有基于时间的操作(如时间窗口)将使用运行相应算子的计算机的系统时钟。每小时的处理时间窗口将包括所有到达特定算子的系统时钟指示整小时的时间之间的记录。例如,如果应用程序在9:15 am开始运行,则第一个一小时的处理时间窗口将包括在9:15 am和10:00 am之间处理的事件,下一个窗口将包括在10:00 am和11:00 am之间处理的事件,依此类推。。
处理时间是最简单的时间概念,不需要流和机器之间的协调。它提供了最佳的性能和最低的延迟。但是,在分布式和异步环境中,处理时间不能提供确定性,因为它容易受记录到达系统(例如从消息队列)速度,记录在系统内部算子之间流动速度,以及中断(调度或其他情况)的影响。
- 事件时间:事件时间是每个事件在事件生产设备上发生的时间。通常在记录进入Flink之前将其嵌入到记录中,并且可以从每个记录中提取事件时间戳。在事件时间中,时间取决于数据,而不取决于任何时钟。事件时间程序必须指定如何生成“事件时间水印”,这是一种表示事件时间进度的机制。该水印机制将在下面的后续部分 中进行介绍。
在理想情况下,事件时间处理将产生完全一致且确定的结果,而不管事件何时到达或它们的顺序如何。但是,除非已知事件是按时间顺序(按时间戳)到达的,否则会在处理事件时间过程中因为等待无序事件导致一定的延迟。由于只能等待有限的时间,因此这限制了事件时间应用程序如何提供确定性。
假设所有数据都已到达,事件时间操作将按预期方式运行,即使在处理无序或迟到的事件或重新处理历史数据时也会产生正确且一致的结果。例如,一个一小时事件时间窗口将包含落入该小时内的带有事件时间戳的所有记录,跟它们到达的顺序或处理时间无关。(有关更多信息,请参见延迟事件部分。)
请注意,有时当事件时间程序实时处理实时数据时,它们将使用一些处理时间操作,以确保它们及时处理。
事件时间和水印
注意:Flink从数据流模型中实现了许多技术。为了对事件时间和水印有一个很好的介绍,请看下面的文章。
- Tyler Akidau著的Streaming 101
- 数据流论文
支持事件时间的流处理器需要一种方法来衡量事件时间进度。例如,当事件时间超过一小时的结尾时,需要通知一个构建一小时窗口的窗口算子,以便该算子可以关闭正在进行的窗口。
事件时间可以独立于处理时间(由时钟衡量的)进行。例如,在一个程序中,算子的当前事件时间可能会稍微小于处理时间(考虑到事件接收的延迟),而两者均以相同的速度进行。另外一个例子,一个流式程序,通过快速转发已经在Kafka主题(或另一个消息队列)中缓冲的一些历史数据的方式,处理遍布几周的事件时间,但处理本身的时间仅为几秒钟。
Flink中衡量事件时间进度的机制是水印。水印作为数据流的一部分流动,并带有时间戳t。一个水印(t)表明该流的事件时间已经达到时间t,这意味着不应该再有更多来自该流时间戳为 t' <= t的元素(即,比水印更早或相等的带时间戳的事件)。
下图显示了带有(逻辑的)时间戳的事件流,并且水印们按序流动。在此示例中,事件是有序的(对于它们的时间戳),这意味着水印只是流中的周期性标记。
水印对于乱序流至关重要,如下图所示,其中的事件未按其时间戳排序。通常,水印是流中点的一个声明,到某个时间戳的所有事件都应该已到达。一旦水印到达算子,算子就可以将其内部事件时间时钟推进到水印的值。
请注意,新创建的一个(或多个)流元素的事件时间继承自生成它们的事件或触发哪些元素创建的水印。
并行流中的水印
水印在源函数处生成或在源函数之后直接生成。源函数的每个并行子任务通常独立生成各自的水印。这些水印们定义了该特定并行源的事件时间。
随着水印们在流式程序中的流动,它们会推进所到达的算子的事件时间。每当算子推进其事件时间时,都会在下游为后续算子生成新的水印。
某些运算符会消耗多个输入流。例如一个union,或带有keyBy(…)或partition(…)函数的算子。这样的算子的当前事件时间是其输入流的事件时间中的最小值。随着其输入流更新其事件时间,算子也将更新。
下图展示了流经并行流的事件和水印,算子跟踪事件时间的例子。
延迟
某些元素可能会违反水印条件,意思是即使水印(t)已发生,更多带有时间戳t'<=t的元素还会发生。事实上,在许多实际情况中,某些元素可以被任意延迟,使得给所有将要发生的事件指定一个确定的事件时间戳是不可能的。 另外,延迟可以有限度,对水印太多延迟通常也不可取,因为它会在事件时间窗口计算中造成太多的延迟。
因此,流程序可能会明确地知道有晚到的元素。 迟到元素是指系统事件时间时钟(被水印标记)之后到达的元素,系统事件时间时钟已经超过迟到元素的时间戳。参考允许延迟获取更多有关如何在事件时间窗口中使用延迟元素的信息。
窗口
聚合事件(例如,计数、总和)在流上的工作方式与在批处理中不同。例如,不可能计算一个流中的所有元素,因为流通常是无限的(无界的)。相反,流上的聚合(计数、总和等)局限于窗户,例如“数过去5分钟”,或“最后100个元素的总和”.
窗户可以由时间驱动(例如:每30秒)或数据驱动(例如:每100个元素)。人们通常区分不同类型的窗户,例如翻滚的窗户(无重叠),滑动窗(重叠),以及会话窗口(由不活动间隙分割)。