apache Flink:单个引擎中的流和批

概要

Apache Flink是一个开源的处理流和批数据的框架。Flink是建立在许多类型的数据处理应用程序的基础上的,包括实时分析、连续数据管道历史数据处理(批处理)和迭代算法(机器学习,图分析)可以作为流水线式的数据流和并行。在这篇论文中,我们提出了Flink架构,展开一组(看似多样化)的应用可以统一在一个执行模型下。

1 引言

数据流处理(即:例如复杂时间处理系统)和静态(批处理)数据进程(即例如MPP(大规模并行)数据数据库和Hadoop)在传统上被认为是俩中非常不同类型的应用程序。它们使用不同的才需要模型和API进行编程,并且通过不同的系统进行执行(比如例如,专用流系统,如Apache Storm, IBM Infosphere Streams,微软的StreamInsight,或Streambase对关系数据库或Hadoop的执行引擎,包括Apache Spark和Apache Drill)传统上批数据分析占据了用例大部分的份额,数据大小和市场,其中流数据分析主要服务于专门的应用。

然而,这一点变得越来越明显,大量如今的大规模的数据处理实际上是随着时间推移不断产生的。例如这些连续的流数据来自网络日志,应用日志,传感器或者改变数据库中应用的状态(事务日志记录),今天的步骤忽略了数据生产的连续性和实时性。因此数据记录是(通常人工的)批量的加入静态的数据集(小时的或者天的月的数据块),然后以在不可知时间的方式进行处理。数据收集工具,工作流管理,调度器程序编排批处理和调度处理,实际上是连续的数据处理管道。架构模式比如lambda架构结合了批和流处理系统已实现多路径计算:一个流式的快速路径以用于即时的模拟结果,以及一个批离线路径用于准确的之后准确结果。所有的这些方法都存在高延迟问题(由批进行处理)、高复杂性(需要连接和协调多个系统,并且实现业务逻辑),以及任意的不准确性,因为时间维度不是由应用程序代码显式处理的。

Apache Flink遵循范例,支持数据流处理作为统一模型,已进行实时分析连续流,以及编程模型和程序引擎中的批处理。与持久化消息队列一起使用,这使得允许任意重放数据流(比如Apache Kafka或者Amazon Kinesis),流处理程序让以下没有区别,实时处理最新事件,在大窗口内定期的聚合数据,或者处理TB级别的历史数据。相反,这些不同类型的计算只是在持久流的不同点开始它们的处理,并且在计算期间保持不同的状态。通过高度灵活的窗口机制,Flink可以计算早起和近似的以及延迟和准确的结果在同一个操作中,避免了为俩个用例组合不同系统的需要。Flink支持不同的时间观念(事件事件,摄入事件,处理时间)以给程序高灵活性以及定义事件应该如何关联。

老旧的流处理以及对于静态数据的复杂查询仍然可以使用批处理

批处理是流处理的特殊情况:这句话非常重要,它指出了批处理是可以看做是一个特殊的在一个大窗口内的有界流。

与此同时,Flink承认有并且会有对专用批处理的需求(和静态数据集交互)。对于静态数据的复杂查询仍然和批处理抽象非常匹配。此外,对于流用例的遗留和分析应用程序仍然需要批处理,目前还没有有效的算法对流数据进行这种处理。批处理是流处理的特殊情况,其中流是有界的记录的顺序和时间并不重要(所有的记录隐式的被一个窗口包含)。Flink有专门的API来处理静态数据集,使用独特的数据结构和算法来处理操作的批版本,比如join或者grouping,并且使用了专门的调度策略。结果是Flink将自己呈现为流运行时之上的成熟和高效的批处理器,包括图形分析和机器学习的库。起源于Stratosphere项目,Flink是Apache 软件基金会的顶级项目,它是由一个庞大而又活跃的社区开发和支持的(在写这篇文章的时候有超过180名开源贡献者),并且已经在生产环境使用了。

这篇的paper的共线如下:

  • 我们提出了同意流和批数据程序的架构,包括与静态数据集相关的特定优化。
  • 我们展示了流,批,迭代和交互分析可以被表示为带容错的流失数据流(在章节3中)
  • 我们讨论我们如何构建一个全方位的留分析系统,具有灵活的窗口机制(章节4),通过展示如何将流、批处理、迭代和交互式分析表示为流数据流。在这数据流顶部的一个全面的批处理器(章节4.1),

2 系统架构

在本节中,我们将Flink的架构作为软件堆栈和分布式系统进行展示。同时Flink的API栈不断的增长,我们可以分为主要的四层:调度,核心,API和库

FlinkML,Gelly和Table都是不同的Flink的组件

Flink的运行时和API 图1展示了Flink的软件栈。Flink的核心是分布式数据流引擎,它执行数据流程序。Flink的运行时程序是有状态数据流链接的数据流。有俩个核心的API:处理有限数据集的DataSet API(通常被称为批处理),处理潜在的可能无边界的数据流(通常称为流处理)。Flink的核心运行时运气可以看错是一个流式数据流引擎,数据集和数据流API创建引擎可执行的运行时程序。因此,它充当公共的结构以抽象有界的(批)和无界的(流)计算。在核心API的上方,Flink捆绑了特定领域的库,和生成数据集数据流的API程序,目前,FlinkML用于机器学习,Gelly用于图形处理,Table用于类似sql的操作。

如图2所示,Flink集群包含了三种类型的进程:客户端,和只少一个的任务管理者。客户端获取程序代码将其转换为数据流图并且提交到工作管理者中。这个传输阶段也会检查操作之间数据交换的数据类型(模式)并创建序列化器和其他特定于类型/模式的代码。数据集程序额外的基于成本的优化查询阶段,类似于相关查询器执行的物理优化(更多细节见4.1章)。

flink中算子是数据流处理的基本计算单元。它定义了数据流中的处理逻辑,每个算子对数据进行某种操作,处理输入数据并生成输出数据。

JobManager协调数据流的分布式执行。它跟踪每个算子和流的状态与进展,调度新的任务协调检查点和恢复。在高可用的步骤中,任务管理者在每个检查点上持久化一组最小的元数据以进行容错,这样备用JobManager就可以重建检查点并从那里恢复数据流执行。真实的数据处理任务在任务管理者中放置。任务管理者执行一个或多个生产流的算子,并且上报它自己的状态到任务管理器。任务管理者维护缓冲池以缓冲或者实现流,网络连接以交换操作之间的数据流。

3 通用的结构:数据流

虽然用户可以使用众多的API来写Flink程序,但是所有Flink程序最终编译为一个公共的表示:数据流图。数据流图通过Flink的运行时引擎执行,批处理(DataSet)和流处理(DataStream)API之下存在公共的层。

3.1 数据流图

数据图在图3中被描述有向无环图(DAG)它的组成为

  1. i:有状态操作
  2. ii:表示操作员产生的数据并且可以供操作员使用的数据流。

因此数据流图是以数据并行的方式执行的,操作并行的加入一个或者更多的实力被叫做子任务(subtask),并且流被切分成一个或多个的流分区(每个子任务一个分区)。有状态操作在特例子下是无状态的,实现了所有的处理逻辑(即过滤,hash join,流窗口函数)。在章节4,我们提供了实现窗口操作的细节。流在不同的模式下在生产者和消费者算子之间分发数据,例如点对点,广播,充分去,扇出和归并。

3.2 通过数据流的数据交换

Flink的中间数据流是对数据在操作之间变换的核心抽象。中间的数据流表示数据的逻辑句柄,通过一个算子产生,可以由一个或多个算子使用。中间流是合乎逻辑的,因为它们指向的数据可能在磁盘上是实体化,也可能不实体化。数据流的特定行为在Flink中由更高的层参数化(即数据集API使用的程序优化器)。

物化代表的是将数据写入存储中。

流水线和块数据交换 流水线化的中间流在当前并发运行的生产者和消费者之间交换数据,导致了流水线并行。作为结果流水线化的流从生产者到消费者传播背压,借助中间缓冲池获取弹性,以补偿短期的吞吐量波动。Flink使用了流水线化的流以进行连续的流程序以及批束流的许多副本,以尽可能避免物化。在阻塞流讲数据提供给消费端之前,阻塞流缓冲所有生产算子的数据,因此将生产算子和消费算子分离到不同阶段。阻塞流自然需要更多的内存,经常溢出到二级存储,并且不会传播反压力。它们被用来隔离相邻的算子(在需要时),以及在存在可能导致分布式死锁的流水线中断算子(例如排序合并连接)的情况下。

平衡延迟和吞吐量 Flink的数据流交换机制是围绕着交换缓冲区来实现的。当数据记录已经在生产侧准备就绪时,它被序列化并分割成一个或多个缓冲区,然后转发给消费者。缓冲区在i满或者ii达到超时条件时发送给消费者。通过设置 缓冲的大小为一个较高的值(几GB)Flink能达到高的吞吐量。通过设置缓冲超时为一个低的值(几毫秒)以实现低的延迟。图4展示了缓冲超时对吞吐量的影响,在30台机器上简单流式Grep作业中传递记录的延迟(120核心)。Flink可以达到20ms的99百分位的延迟。响应的吞吐量是150w个事件每秒。随着我们增加缓冲的超时我们看到随着吞吐量的增加延迟也在增加,直到达到完全的吞吐量(即 直到缓冲区填满的速度比超时到期来的块。)在缓冲超时为50ms时,集群集群达到了吞吐量超过8000万事件每秒,此时第99百分位的延迟为50ms。

控制事件 除了交换数据,Flink中的流还通信不同类型的控制事件。这些是算子在数据流中注入的特殊事件,并且与流分区内所有的其他数据记录和事件一起按顺序传递。通过一旦事件到来通过执行特定的操作,接受算子对这些事件做出反应。Flink使用了许多特殊类型的控制事件,包括:

Bulk Synchronous Parallel (BSB)

BSP 是一种基于超步(superstep)概念的分布式计算模型,由 Leslie Valiant 在 1990 年提出。该模型将分布式计算划分为一系列同步阶段,每个阶段被称为“超步”。它的核心思想是:

计算阶段:所有并行任务(workers)独立执行计算。
通信阶段:任务之间通过消息或共享变量交换数据。
同步阶段:在当前超步结束后,所有任务必须等待同步,确保所有任务都完成当前超步后才能继续下一个超步。

  • 检查点屏障,通过划分流到每一个检查点前和检查点后来协调检查点
  • 水印(watermark), 通知事件事件内的进度(在4.1章讨论)
  • 迭代屏障 ,流分区到达了超级步的末端,基于循环数据流Bulk/StaleSynchronous-Parallel迭代算法(见5.3章)

如上所述,控制事件假设流分区保存了记录的顺序。为了这个目的,Flink中消费单个流分区的单一算子,保证记录以FIFO的顺序处理。然而,接收到多个流分区的操作符按顺序合并流,以保持流的数据以避免背压。因此Flink中的流数据流在重分区或者广播之后不提供任何顺序性保证,并且将处理乱序记录的责任留给操作员执行。我们发现这种安排提供了最有效的设计,大部分的操作必须要特定的顺序(如 hash-join,map),需要处理乱序到达的算子(如时间窗口),可以更高效地在算子逻辑中完成这一补偿。

3.3 故障容忍

flink提供了可靠的执行器和严厉的exactly-once-process 一致性保证。通过检查点和分区重试来处理故障。为了有效的提供这些保证,该制度的一般假设为,数据源是持久化的并且可以重放的。资源的一个例子是文件和持久化的消息队列 (如Apache 的kafka)。事实上,也可以通过资源算子的状态中,保留预写日志来合并非持久性存储源。

Apache Flink的检查点机制构建在分布式持久化快照的概念上已到达exactly-once处理保证。数据流可能具有无界的特征,让重新计算变得不切实际,对于一个长时间的作业,可能需要数月的时间进行计算。为了限制恢复的时间,Flink会定期对算子的状态进行快照,包括每隔一段时间输入流的当前位置。

核心的挑战在于获取所有并行算子的一致性快照,而不会停止拓扑的执行。本质上所有算子的快照应该在计算上引用相同的逻辑时间。这个机制被用在Flink中叫做Asynchronous Barrier Snapshotting(ABS)。屏障是注入到输入流中的控制记录,它对应着逻辑时间,并在逻辑上将流分离到部分,其效果应该包含在当前的快照和稍后将被快照的部分中。

一个算子从上流和接受到屏障,然后首先执行校准阶段,确保收到所有输入的屏障。之后算子写入它的状态(即 滑动窗口的内容或者自定义数据结构)到稳态存储(即存储后端可以是外部系统例如HDFS)。一旦状态被备份,算子转发屏障到下游,最终所有的算子将会注册一个它状态的快照并且全局快照会被完成。例如图5展示了快照t2包含了所有算子状态,这是小号t2之前所有记录的结果。ABS类似于一步分布式快照的Chandy-Lamport算法。由于Flink程序的DAG结构,ABS无需对正在传输中的记录做检查点操作,而只需要以来对其阶段将所有记录的影响应用到算子中。这保证了需要写入可靠存储的数据保持在理论上的最小值(即 只有算子的当前状态)。

故障恢复将所有操作符状态恢复到从上次成功快照中获取的各自状态,重新启动有快照的最新屏障开始的输入流。恢复时需要计算的最大数量被限制为俩个连续屏障之间输入记录的数量。此外,通过额外重放在直接上游子任务重缓冲未处理的记录,可以恢复部分失败的子任务。

ABS提供了几个好处

  1. 它保证了exactly-once状态更新,不需要任何的计算暂停
  2. 它和其他形式的控制消息完全解耦(即,通过出发窗口计算的时间和,从而不将窗口机制检查点间隔的倍数)
  3. 它完全从持久化机制中解耦,允许状态备份到文件系统数据库,取决于Flink的更大的环境。

3.4 迭代数据流

反馈边 feedback edge 是指在有向图中引入的一种特殊边,它允许不分数据计算结果从某些节点返回到前面的节点或者重新进入图的部分,从而实现循环或者迭代计算。通常情况下,DAG 是无环的,但通过反馈边,可以在逻辑上实现某种循环行为,用于支持迭代式操作。这种机制在许多分布式数据处理平台(如 Flink)中用于处理需要多轮计算的场景,比如机器学习算法中的迭代训练或图计算中的 PageRank 算法。

迭代步:是指在进行迭代计算时,每一乱迭代中所包含的逻辑或者任务步骤。通常迭代器需要多轮处理,每一轮会将结果反馈到下一个阶段

反馈通道:feedback channel)指的是在迭代计算中,数据从某个处理步骤返回并作为下一轮迭代输入的通信路径。它是迭代过程的核心机制之一,使得每轮计算的结果可以反馈到迭代的前一步骤,允许在多个迭代轮次中逐步更新计算结果。

增量的处理和迭代对应用程序至关重要,比如图处理和机器学习。在数据并行处理平台中,对迭代的支持通常依赖于为每次迭代提交一个新作业,或者添加额外的节点到运行时DAG或者反馈的边缘。Flink中的迭代是通过迭代步(iteration steps)来实现的,特殊操作符本身可以包含执行图(图6)。为了维护基于DAG的运行时和调度器,Flink允许迭代“头”和“尾”任务,这些任务与反馈边隐含地联系在一起。这些任务的作用是建立一个积极的反馈通道到迭代步骤,并提供协调一遍处理在反馈通道中传输的数据记录。实现任何类型的结构化并行迭代模型都需要协调,比如Bulk Synchronous Parallel模型利用控制事件实现,我们在4.4节和5.3阶中解释如何在数据流和数据集API实现迭代。

4 基于数据流的流分析

Flink的数据流API在Flink运行时之上实现了完全的流分析框架,包裹管理时间的机制,例如乱序的时间处理,定义窗口,维护和更新用户定义的状态。流API是基于数据流(DataStream)的概念的,数据流是给定类型的元组(可能是无界的)不可变集合。因为Flink的运行时已经提供了流水线数据传输持续的有状态算子以及用于一致性状态更新的容错机制,在它上面叠加流处理器本质上归结为实现一个窗口系统和一个状态窗口。如前所属,这些对于运行时是不可见的,运行时将窗口视为有状态算子的实现。

4.1 时间概念

Flink区分俩中时间概念

  1. 事件时间,它代表了事件发生的时间(传感器与信号关联的时间戳,比如手机设备)
  2. 处理时间,它是机器处理数据的墙种时间

在分布式系统中,事件时间和处理时间中有一定的差距。用于根据事件时间语义获得答案,这种倾斜可能意味着延迟。为了避免任意的延迟,这些系统定期插入时间被叫做低水印的特殊事件,标志着全局的处理方式。以实践进度为例,水印包括了一个时间属性t,表示所有低于t事件都已输入算子。水印帮助执行引擎以正确的事件顺序处理事件并序列化操作,例如通过同意度量进行窗口的计算。

水印起源于拓扑的源,其中我们可以确定未来元素中的固有时间。水印从源传播到数据流的其他算子。算子决定如何对水印做出反应。简单的操作,比如map或者filter只是转发它们接受到的水印,而更加复杂的基于水印计算的操作(即事件时间窗口)首先计算水印触发的结果,然后转发。如果一个操作有多个输入,系统只转发到来谁赢最小的到算子从而确保正确的结果。

Flink程序是基于依赖于本地机器始终的处理时间,因此时间的概念不是那么可靠的,它可能会导致恢复后的重放不一致。然而,它们表现出较低的延迟。基于事件时间的程序提供了更可靠的语义,但是由于时间时间-处理时间的时延,可能会出现延迟。Flink包含了第三种时间概念作为事件时间的特例叫做摄取时间(ingestion-time),它代表着进入Flink的时间是什么。这样可以实现比事件时间更低的处理延迟,并产生比处理时间更准确的结果。

4.2 有状态流处理

Flink DataSteam API中的大部分操作看起来都像一个函数,无副作用的算子,它们为高效的状态计算提供支持。状态多余许多应用程序都是必要的,比如机器学习模型构建,图分析,用户会话处理和窗口聚合。根据用例的不同,有大量不同类型的状态。例如,状态有的时候可以非常简单如计数或者求和,或者更加复杂如常用在机器学习中的分类树以及大稀疏矩阵。流窗口是有状态的算子,它将记录分配给作为算子状态的一部分保存在内存中。

在Flink中状态是显式的并且通过以下的方式提供:

  1. 在算子范围内用于静态注册显示局部变量的操作符接口或者注释,
  2. 用于声明分区键值对状态和它相关操作的算子状态的抽象

在 Flink 中,StateBackend 是一个接口,用于管理和存储应用程序中的状态(例如,算子状态)。它负责在分布式环境中持久化和访问状态数据,确保系统能够在容错和故障恢复的情况下恢复和保持状态。

用户也可以配置状态如何存储,使用系统提供的StateBackend抽象来进行检查点,从而允许在流应用中高柔性的在调用状态管理。Flink的检查点机制(在3.3章中讨论,保证任何注册状态都是持久的,并且只有一次语义更新)。

4.3 流窗口

在无限流上的增量计算通常在不断发展的逻辑视图上进行评估,叫做窗口。Apache Flink在一个有状态的算子中集成了窗口,该操作符通过由是哪个核心函数组成的灵活声明来进行配置:一个窗口分配器,可选的触发器和驱逐器。所有的这三个函数都可以从一个通用的预定义池中选择(即滑动时间窗口)或者可以通过用户被清晰的定义(即用户定义函数)。

更具体的说,复制器负责分配每个记录给逻辑窗口。例如,当决策来到事件时间窗口,这个决定可以基于记录的时间戳。注意在滑动窗口的情况下,一个元素可以属于多个逻辑窗口。可选触发器定义了合适执行和窗口定义相关的操作。最终可选的驱逐器决定在每个窗口保留哪条记录。Flink 的窗口分配过程具有独特的能力,能够涵盖所有已知的窗口类型,如周期性时间窗口、计数窗口、标点符号窗口、地标窗口、会话窗口和增量窗口。注意,Flink的窗口概念无缝地集成了无序处理,类似Google Cloud Dataflow,并且在原则上包含了这些窗口模型。例如,下面是一个范围为6秒的窗口定义,每2秒滑动一次(分配器)。一旦水印通过窗口的末端窗口的结果就被计算出来(触发器)。

SlidingTimeWindows.of() 创建一个滑动时间窗口(sliding time window)。滑动窗口在时间上进行切分,它会在指定的时间间隔内处理数据,并根据滑动步长不断滑动,覆盖新的数据段。

Time.of(6, SECONDS):表示窗口的大小为 6 秒,即每个窗口包含的数据是连续的 6 秒的数据。

Time.of(2, SECONDS):表示窗口的滑动步长为 2 秒,即窗口每 2 秒滑动一次,处理下一个 6 秒的数据。

这个滑动时间窗口将以 6 秒为一个窗口大小,每 2 秒滑动一次,覆盖新的数据。

trigger() 方法用于设置窗口触发器。触发器决定了何时计算窗口中的数据。

EventTimeTrigger.create():表示基于事件时间的触发器。这意味着窗口会根据事件的时间戳来决定何时触发窗口计算,而不是依赖于处理时间(即数据到达的时间)。事件时间触发器通常与水印(watermarks)一起使用,以便正确地处理乱序事件。

stream
.window(SlidingTimeWindows.of(Time.of(6, SECONDS), Time.of(2, SECONDS))
.trigger(EventTimeTrigger.create())

全局窗口创建单个逻辑组。以下的例子定义了全局窗口(即分配器)每1000个事件调用一次(即触发器)同时保持最后100个元组(即驱逐器)

stream
.window(GlobalWindow.create())
.trigger(Count.of(1000))
.evict(Count.of(100))

记住如果上面的流在窗口之间按键进行分区,窗口操作是局部的,因此不需要工作节点之间进行协调。这种机制可以被用来实现各种各样的窗口功能。

4.4 异步的流迭代

在 Apache Flink 中,feedback stream(反馈流)是指从某个操作或算子(operator)的输出重新反馈到该操作或算子的输入,通常用于实现迭代计算或流式处理中的某种自反馈机制。

流中的循环对于一些应用是必不可少的,比如增量构建和机器训练模型,强化学习和图算法。在大多数的这些例子中,反馈循环不需要协调。异步迭代器涵盖了流应用程序的沟通需求,并且不同于基于有限数据结构化迭代的并行优化问题。如同在3.4章图6中展示的,在没有启用迭代控制机制的情况下,Apache Flink的执行模型已经涵盖了异步迭代。此外为了容错保证,反馈流被视为隐式迭代头算子中的算子状态,并且是全局快照的一部分。DataStream API 允许明确地定义反馈流,并且可以轻松地支持基于流的结构化循环以及进度跟踪。

5 基于数据流的批分析

有界的数据集是无界数据集的特例。因此,窗口中的所有的输入数据可以表示为批处理,而批处理完全被Flink的上述特性所覆盖。然而 i 语法(即批计算的API)可以被简化(即他们不需要人为的全局窗口定义) 并且ii 处理有界数据集的程序可以进行额外的优化,以及策略调度。

Flink的批处理方法如下

  • 批计算和流计算在相同的运行时进行。运行时的执行器可以参数化以将大型的计算分解为连续调度的独立阶段。
  • 当定时快照的开销较大时关闭快照。相反错误恢复可以通过重放来自最后物化的中间流(可能是源)来实现容错。
  • 阻塞算子(如排序)简化了算子的实现,直到它们消耗了所有的输入。运行时不知道算子是否阻塞。这些操作符使用Flink提供的托管内存(在JVM堆上或堆外),如果它们的输入超出了它们的内存界限,就会溢出到磁盘。
  • 专用的DataSet API提供了批计算即有届的容错数据集数据结构以及数据集变换(join,aggregation,iteration)的类似抽象。
  • 查询优化层将数据集程序转化为有效的可执行结构

下面我们将更加详细的描述这些概念。

5.1 查询优化器

计划等价性:某个查询中可能有多个等价的计划,比如走A索引和B索引都可以。但是A索引字段比较小,所以走A索引的成本低。

成本建模:对不同的计划的资源进行建模,估算最低成本的计划。

有趣性传播:在数据库查询执行计划中,“有趣的属性”是指可能影响查询性能的元数据或性质。常见的有趣属性包括:排序,分区,索引聚合。(比如数据原来就是按主键排序的就不需要再排一次了)

Cardinality基数是查询或中间操作结果集中包含的记录数。基数估计,可以用来预测各个操作返回的函数。

Flink的优化器基于并行的数据库系统的技术上,比如计划等价,成本建模和有趣性传播。然而Flink的数据流程序包含大量用户自定义函数(UDF)的有向无环图(DAG)不允许传统的应用于数据库的技术开箱即用,因为算子隐藏了操作的语义。出于同样原因,技术和成本估计方法同样难以使用。Flink的运行时支持多种执行器策略包括复制和广播数据传输,基于基于排序的group和基于排序和哈希的连接实现。Flink优化器基于有趣数学传播的概念枚举了不同的执行计划。使用基于成本的方法在多个物理计划中进行选择。成本包括了网络和磁盘IO以及CPU开销。为了基数估计问题在用户自定义函数中的问题,Flink的优化器可以使用程序员提供的提示。

5.2 内存管理

建立在数据库的技术上,Flink序列化数据进入内存段,而不是分配对象到JVM的堆中,以表示缓冲的在使用的对象。排序和join尽可能的直接对二进制数据进行操作,将序列化和反序列化的开销保持在最低并且在需要的时候将部分数据溢出到磁盘。通过保持数据在二进制表示和堆外进行处理,Flink设法减少垃圾收集的开销,并且使用了搞笑的缓存和健壮的算法,在内存压力下优雅的扩展。

5.3 批迭代

在Flink中,Delta Iterations 是一种特定类型的迭代处理模式,旨在通过减少每次迭代中的数据量来提高迭代计算的效率。

在传统的迭代计算中,整个数据集会在每一轮迭代中被完全计算,并且可能在每一轮中都需要传输和处理大量数据。而在Delta Iterations中,仅计算和传递上一次迭代中发生变化的数据部分(即“delta”部分),从而显著减少每轮迭代所需处理的数据量。这种方法对于需要反复迭代的算法(例如图计算和机器学习中的某些优化算法)特别有效。

迭代图分析,批量梯度下降和有技术已经在Bulk Synchronous Parallel(BSB)和Stale Synchronous Parallel(SSP)模块的基础上实现。通过使用迭代控制事件,Flink的执行模型允许任何类型的结构迭代逻辑在上面实现。例如在BSP执行的情况下,迭代控制事件标记着迭代计算中超级步的开始和结束。最后,Flink介绍了进一步的新型优化技术,如delta迭代的概念,它可以利用稀疏计算依赖性,Delta迭代已经被Flink的图形API Gelly所利用。

6 相关工作

在今天已经有大量的引擎进行分布式批和流的分析与处理。我们将系统主要分类如下。

MPP数据库:是一种分布式数据库架构。通过将计算任务分配给多个独立的处理单元,每个节点处理一部分自己的数据实现高度的并行性和可扩展性.Hive就是MPP数据库

批处理:Apache Hadoop是一个最受欢迎的处理大规模数据分析的开源系统,他基于了Mapreduce样板。Dryad在一般基于DAG的数据流中引入了嵌入式的用户定义函数被SCOPE丰富,它是一个语言和SQL优化器。Apache Tez可以看做是一个开源Dryad的实现。MPP数据库和最近的开源实现比如Apache Drill和Impala将API的限制变为SQL实体。类似Flink,Apache的Spark是一个数据处理框架基于DAG实现了执行引擎,提供了SQL优化,执行基于驱动的迭代,并且将无界试做微批。作为对比,Flink是为一个系统整合了:

  1. 分布式数据流的营运形式,利用批处理和流工作负载流水线执行
  2. 通过轻量级的检查点实现了exactly-once状态
  3. 原生的迭代程序
  4. 复杂的窗口语义支持乱序处理。

流处理 在学术上和商业上已经有大量流处理的前期工作,比如SEEP,Naiad,Microsoft StreamInsight和IBM Steams。这些系统中的许多都是基于数据库社区的研究。以上的大多数系统要么是

  1. 学术原型
  2. 闭源商业产品
  3. 不能在商用服务器集群上水平扩展计算。

许多最近在数据流中的方法允许水平的扩展并且具有较弱的一致性状态保证组合的数据流算子(在Apache Storm和Samza中at-least-once)。值得注意的是,例如无需处理(OOP)的概念获得了极大的关注并被MillWheel,MillWheel 是 Google 内部版本的后续商业化执行器 Apache Beam/Google Dataflow 的前身。Millwheel作为一次低延迟流处理和OOP的概念证明,因此对Flink的影响很大。据我们所知Flink是唯一的开源项目实现了

  1. 支持事件时间和乱序时间处理
  2. 在Exactly-once语义下提供一致的管理状态
  3. 达到了高吞吐量和低延迟,同时服务于批和流。

7 鸣谢

8 结论

在这篇论文我们提出了Apache Flink,一个平台它实现了全面的数据流引擎设计以执行流和批的分析。通过批和不同参数的数据流API,Flink数据流引擎对待算子状态和逻辑中间状态作为一等公民。流API建立在Flink的流数据流引擎上提供保持回复状态以对流串口进行分区转换和聚合的方法。虽然批计算在理论上是一种在流计算的特殊情况,Flink对它们进行了特殊处理,通过使用查询优化器和实现阻塞操作符来优化它们的执行,它可以优雅的在缺乏内存的情况下溢出到磁盘。

Last modification:December 4, 2024
如果觉得我的文章对你有用,请随意赞赏