当前位置: 首页 > 科技观察

Flink如何统一批处理引擎

时间:2023-03-12 05:25:37 科技观察

本文转载自微信公众号《大数据技术派》,作者柯光。转载本文请联系大数据技术群公众号。2015年,Flink的作者写了论文ApacheFlink:StreamandBatchProcessinginaSingleEngine。本文以这篇论文为指导,详细阐述了Flink内部是如何设计和实现批流集成架构的。前言unify-blocks通常我们所说的Flink中的batch-flow集成就是指这四个方向,其中Runtime就是Flink运行时的实现。数据交换模型Flink对流式作业和批作业有统一的执行模型。unify-execFlink中每个Task的输出都会用IntermediateResult进行封装。流作业和批作业内部没有明确的划分,而是通过不同类型的IntermediateResult来表达PIPELINED和BLOCKING两种数据交换模型。在了解数据交换模型之前,我们先看看为什么Flink不区分作业类型。这样做有什么好处?Unify-example如上图所示。如果我们有一个作业需要将批处理作业的执行结果作为流式作业的启动输入,那怎么办呢?这个作业是批作业还是流作业?显然,不能用我们的常识来定义,现有的行业方法也是一样的,把这个job拆分成两个job,当然可以先跑batchjob再跑streamjobs,但是人工运维的成本是也足够高:需要外部存储来管理批处理作业的输出数据。需要一个支持批处理作业依赖的调度系统。如果要实现这样的作业,那么首先执行该作业的计算引擎的作业属性就不能将批作业和流作业强绑定。那么Flink能不能满足这样的需求呢?我们先来看看数据交换的具体细节,最后我们一起来看看这个工作的可行性。下面以PIPELINED数据交换模型为例,看看它是如何设计的:在unify-pipelinedPIPELINED模式下,RecordWriter将数据放入Buffer中,根据Key的路由规则发送到对应的Partition,以及Partition将自己的数据封装到Reader中放到队列中,让NettyServer从队列中读取数据发送给下游。我们将数据交换方式改为BLOCKING,我们会发现这种设计也是可行的。Partition向文件写入数据,Reader维护文件句柄。上游任务完成后调度下游任务,下游任务通过NettyClient的PartitionRequest唤醒相应的Partition和Reader,向下游拉取数据。调度模型有两种调度模型,LAZY和EAGER。默认情况下,流作业使用EAGER,批处理作业使用LAZY。EAGER很好理解,因为StreamingJobs是一个AllorNothing的设计,要么所有的任务都运行,要么不运行。LAZYLAZY模式是先调度上游,等待上游产生数据或完成,再调度下游。有些类似于Spark中的Stage执行方式。从RegionScheduling可以看出无论是EAGER还是LAZY都无法完成我们刚刚提出的批流混合任务,所以社区提出了RegionScheduling来统一批流作业的调度。我们先来看看Region是如何定义的:unify-region以Join算子为例,我们都知道如果Join算子的两个输入都是海量数据,那么我们需要等待两个输入的数据都完全在执行Join操作之前准备好,所以Join两个输入边对应的数据交换模式应该对应BLOCKING模式。我们可以根据BLOCKING边将作业划分为多个子区域,如上图虚线所示。如果实现RegionScheduling,我们上面说的batchmixedjob可以把streamingjob的dark部分划分成一个Region,而batchjob的light部分可以划分成多个Region,其中light部分就是dark部分是Region的输入,所以根据RegionScheduling的原则,第一个Region会先被调度。总结上面提到的数据交换模型和调度模型,简单来说,其实就是两句话:1.实现了使用PIPELINED模型运行batchjob。使用PIPELINED模型运行流式作业和使用BLOCKING模型运行批处理作业没有错。小说。这里提到,以PIPELINED模式运行批处理作业,主要针对实时分析场景。以Spark为例,在大多数发生shuffle或aggregation的场景下,都会有磁盘放置行为,调度顺序是stagebystage,大大降低了数据处理的实时性,使用PIPELINED模式会在一定程度上提高性能。可能有人会问像Join这样的算子如何利用PIPELINED数据交换模型实现无位移操作?事实上,Flink也会放置磁盘,但不是在Join的两个输入端放置磁盘,而是将两个输入端的数据传输给Join算子,当内存无法容纳时才放置磁盘。Spark的行为和海量数据没有本质区别,但是当数据量适中,内存能够容纳的时候会带来很大的好处。2集成了调度系统的部分功能。在基于Regions调度作业时,Flink本身并不关心运行在Regions内部的是Stream作业还是Batch作业。更关心Region之间的依赖关系。在一定程度上,利用这种调度模型,我们可以把以往需要拆分成多个作业的执行方式,放到一个作业中去执行,比如上面提到的batch-flowmixedjob。