通常咱们在 Flink 中说批流一体指的是这四个方向,其中 Runtime 便是 Flink 运行时的实现。
数据交换模型
Flink 对于流作业和批作业有一个对立的执行模型。
Flink 中每个 Task 的输入会以 IntermediateResult 做封装,外部并没有对流和批两种作业做一个明确的划分,只是通过不同类型的 IntermediateResult 来表白 PIPELINED 和 BLOCKING 这两大类数据交换模型。
在理解数据交换模型之前,咱们来看下为什么 Flink 对作业类型不作辨别,这样的益处是什么?
如上图所示,如果咱们有一个工作须要将批式作业执行后果作为流式作业的启动输出,那怎么办?这个作业是算批作业还是流作业?
很显然,以咱们的常识是无奈定义的,而现有的工业界的方法也是如此,将这个作业拆分为两个作业,先跑批式作业,再跑流式作业,这样当然能够,然而人工运维的老本也是足够大的:
须要一个外界存储来治理批作业的输入数据。
须要一个反对批流作业依赖的调度零碎。
如果冀望实现这样一个作业,那么首先执行这个作业的计算引擎的作业属性就不能对批作业和流作业进行强绑定。大数据培训那么 Flink 是否实现这样的需要呢?咱们先来看看数据交换的具体细节,最初再来一起看看这个作业的可行性。
咱们以 PIPELINED 数据交换模型为例,看看是如何设计的:
PIPELINED 模式下,RecordWriter 将数据放入到 Buffer 中,依据 Key 的路由规定发送给对应的 Partition,Partition 将本人的数据封装到 Reader 中放入队列,让 Netty Server 从队列中读取数据,发送给上游。
咱们将数据交换模式改为 BLOCKING,会发现这个设计也是同样可行的。Partition 将数据写入到文件,而 Reader 中保护着文件的句柄,上游工作完结后调度上游工作,而上游工作通过 Netty Client 的 Partition Request 唤醒对应的 Partition 和 Reader,将数据拉到上游。
调度模型
有 LAZY 和 EAGER 两种调度模型,默认状况上流作业应用 EAGER,批作业应用 LAZY。
EAGER
这个很好了解,因为流式作业是 All or Nothing 的设计,要么所有 Task 都 Run 起来,要么就不跑。
LAZY
LAZY 模式就是先调度上游,期待上游产生数据或完结后再调度上游。有些相似 Spark 中的 Stage 执行模式。
Region Scheduling
能够看到,不论是 EAGER 还是 LAZY 都没有方法执行咱们方才提出的批流混合的工作,于是社区提出了 Region Scheduling 来对立批流作业的调度,咱们先看一下如何定义 Region:
以 Join 算子为例,咱们都晓得如果 Join 算子的两个输出都是海量数据的话,那么咱们是须要等两个输出的数据都齐全筹备好能力进行 Join 操作的,所以 Join 两条输出的边对应的数据交换模式对应的应该是 BLOCKING 模式,咱们能够依据 BLOCKING 的边将作业划分为多个子 Region,如上图虚线所示。
如果实现了 Region Scheduling 之后,咱们在下面提到的批流混合的作业就能够将深色局部流式作业划为一个 Region,浅色局部批式作业再划分为多个 Region,而浅色局部是深色局部 Region 的输出,所以依据 Region Scheduling 的准则会优先调度最后面的 Region。
总结
下面提到了数据交换模型和调度模型,简略来讲其实就两句话:
1 实现了用 PIPELINED 模型去跑批式作业
用 PIPELINED 模型跑流式作业和用 BLOCKING 模型跑批式作业都是没有什么离奇的。这里提到用 PIPELINED 模式跑批作业,次要是针对实时剖析的场景,以 Spark 为例,在大部分呈现 Shuffle 或是聚合的场景下都会呈现落盘的行为,并且调度程序是一个一个 Stage 进行调度,极大地升高了数据处理的实时性,而应用 PIPELINED 模式会对性能有肯定晋升。
可能有人会问相似 Join 的算子如何应用 PIPELINED 数据交换模型实现不落盘的操作?事实上 Flink 也会落盘,只不过不是在 Join 的两个输出端落盘,而是将两个输出端的数据传输到 Join 算子上,内存撑不住时再进行落盘,海量数据下和 Spark 的行为并没有本质区别,然而在数据量中等,内存可包容的状况下会带来很大的收益。
2 集成了一部分调度零碎的性能
依据 Region 来调度作业时,Region 外部跑的具体是流作业还是批作业,Flink 本身是不关怀的,更关怀的 Region 之间的依赖关系,肯定水平上,利用这种调度模型咱们能够将过来须要拆分为多个作业的执行模式放到一个作业中来执行,比方下面提到的批流混合的作业。