flink 调度概述

Intermediate / Inter mi di ei te/
四层图
在这里插入图片描述
在这里插入图片描述

一个 Flink 流式作业,从 Client 提交到 Flink 集群,到最后执行,总共会经历四种不同的状态。
总的来说:
1、Client 首先根据用户编写的代码生成 StreamGraph,然后把 StreamGraph 构建成 JobGraph 提
交给 Flink 集群主节点
2、然后启动的 JobMaster 在接收到 JobGraph 后,会对其进行并行化生成 ExecutionGraph 后调度
启动 StreamTask 执行。
3、StreamTask 并行化的运行在 Flink 集群中的,就是最终的物理执行图状态结构

Flink 中的执行图可以分成四层:StreamGraph ==> JobGraph ==> ExecutionGraph ==> 物理执行图。
StreamGraph:是根据用户通过 Stream API 编写的代码生成的最初的图。用来表示程序的拓扑结构。
JobGraph:StreamGraph 经过优化后生成了 JobGraph,提交给 JobManager 的数据结构。主要的优
化为,将多个符合条件的节点 chain 在一起作为一个节点,这样可以减少数据在节点之间流动所需要的
序列化反序列化传输消耗。
ExecutionGraph:JobManager 根据 JobGraph 生成 ExecutionGraph。ExecutionGraph 是
JobGraph 的并行化版本,是调度层最核心的数据结构。
物理执行图:JobManager 根据 ExecutionGraph 对 Job 进行调度后,在各个 TaskManager 上部署
Task 后形成的图,并不是一个具体的数据结构

上面这张图清晰的给出了 Flink 各个图的工作原理和转换过程。其中最后一个物理执行图并非 Flink 的
数据结构,而是程序开始执行后,各个 Task 分布在不同的节点上,所形成的物理上的关系表示:
1、从 JobGraph 的图里可以看到,数据从上一个 operator(JobVertex) 流到下一个
operator(JobVertex) 的过程中,上游作为生产者提供了 IntermediateDataSet,而下游作为消
费者需要 JobEdge。事实上,JobEdge 是一个通信管道,连接了上游生产的 dataset和下游的
JobVertex 节点
2、在 JobGraph 转换到 ExecutionGraph 的过程中,主要发生了以下转变:
(1) 加入了并行度的概念,成为真正可调度的图结构
(2) 生成了与 JobVertex 对应的 ExecutionJobVertex,ExecutionVertex,与IntermediateDataSet 对应的
IntermediateResult 和IntermediateResultPartition 等,并行将通过这些类实现
3、ExecutionGraph 已经可以用于调度任务。我们可以看到,Flink 根据该图生成了一一对应的
Task,每个 Task 对应一个ExecutionGraph 的一个 Execution。Task 用 InputGate、
InputChannel 和 ResultPartition 对应了上面图中的 IntermediateResult和 ExecutionEdge

那么,设计中为什么要设计这么四层执行逻辑呢?它的意义是什么?
1、StreamGraph 是对用户逻辑的映射
2、JobGraph 在 StreamGraph 基础上进行了一些优化,比如把一部分操作串成 chain 以提高效率
3、ExecutionGraph 是为了调度存在的,加入了并行处理的概念
4、物理执行结构:真正执行的是 Task 及其相关结构

名词解释:
1) StreamGraph:根据用户通过 Stream API 编写的代码生成的最初的图
(1) StreamNode:用来代表 operator 的类,并具有所有相关的属性,如并发度、入边和出边等。
(2) StreamEdge:表示连接两个 StreamNode 的边。
2) JobGraph: StreamGraph 经过优化后生成了 JobGraph,提交给 JobManager 的数据结构。
(1) JobVertex:经过优化后符合条件的多个 StreamNode 可能会 chain 在一起生成一个JobVertex,
即一个 JobVertex 包含一个或多个 operator, JobVertex 的输入是 JobEdge,输出是IntermediateDataSet。
(2) IntermediateDataSet:表示 JobVertex 的输出,即经过 operator 处理产生的数据集。
producer 是 JobVertex, consumer 是 JobEdge。
(3)JobEdge:代表了 job graph 中的一条数据传输通道。source 是 IntermediateDataSet, target 是 JobVertex。
即数据通过 JobEdge 由 IntermediateDataSet 传递给目标 JobVertex。
3) ExecutionGraph: JobManager 根据 JobGraph 生成 ExecutionGraph。
ExecutionGraph 是 JobGraph 的并行化版本,是调度层最核心的数据结构
(1) ExecutionJobVertex : 和 JobGraph 中 的 JobVertex 一 一 对 应 。 每 一 个
ExecutionJobVertex 都有和并发度一样多的 ExecutionVertex。
(2) ExecutionVertex:表示 ExecutionJobVertex 的其中一个并发子任务,输入是
ExecutionEdge,输出是 IntermediateResultPartition。
(3) IntermediateResult:和 JobGraph 中的 IntermediateDataSet 一一对应。一个
IntermediateResult 包含多个 IntermediateResultPartition,其个数等于该 operator 的并发度。
(4) IntermediateResultPartition:表示 ExecutionVertex 的一个输出分区,
producer 是ExecutionVertex, consumer 是若干个 ExecutionEdge。
(5)ExecutionEdge:表示 ExecutionVertex 的输入, source 是 IntermediateResultPartition,
target 是 ExecutionVertex。 source 和 target 都只能是一个。
(6) Execution:是执行一个 ExecutionVertex 的一次尝试。当发生故障或者数据需要重
算的情况下 ExecutionVertex 可能会有多个 ExecutionAttemptID。一个 Execution 通过
ExecutionAttemptID 来唯一标识。 JM 和 TM 之间关于 task 的部署和 task status 的更新都
是通过 ExecutionAttemptID 来确定消息接受者。

从这些基本概念中,也可以看出以下几点:
⚫ 由于每个 JobVertex 可能有多个 IntermediateDataSet,所以每个 ExecutionJobVertex
可能有多个 IntermediateResult,因此,每个 ExecutionVertex 也可能会包含多个
IntermediateResultPartition;
⚫ ExecutionEdge 这里主要的作⼀是把 ExecutionVertex 和 IntermediateResultPartition
连接起来,表示它们之间的连接关系。

4) 物理执行图: JobManager 根据 ExecutionGraph 对 Job 进行调度后,在各个
TaskManager 上部署 Task 后形成的“图”,并不是一个具体的数据结构。
(1) Task: Execution 被调度后在分配的 TaskManager 中启动对应的 Task。 Task 包裹
了具有用户执行逻辑的 operator。
(2) ResultPartition:代表由一个 Task 的生成的数据,和 ExecutionGraph 中的
IntermediateResultPartition 一一对应。
(3) ResultSubpartition:是 ResultPartition 的一个子分区。每个 ResultPartition 包含多个
ResultSubpartition,其数目要由下游消费 Task 数和 DistributionPattern 来决定。
(4)InputGate:代表 Task 的输入封装,和 JobGraph 中 JobEdge 一一对应。每个 InputGate
消费了一个或多个的 ResultPartition。
(5) InputChannel:每个 InputGate 会包含一个以上的 InputChannel,和 ExecutionGraph
中的 ExecutionEdge 一一对应,也和 ResultSubpartition 一对一地相连,即一个 InputChannel
接收一个 ResultSubpartition 的输出。

猜你喜欢

转载自blog.csdn.net/m0_46449152/article/details/114273630