Flink源码阅读笔记——StreamGraph、JobGraph、ExecutionGraph

在具体执行环节中,考虑并行子任务的分配、数据在任务间的传输,以及合并算子链的优化,将逻辑流图转换为物理数据流图。
StreamGraph——JobGraph——ExecutionGraph
在这里插入图片描述

  1. 逻辑流图(StreamGraph)
    这是根据用户通过 DataStream API编写的代码生成的最初的DAG图,用来表示程序的拓扑结构。这一步一般在客户端完成。
    我们可以看到,逻辑流图中的节点,完全对应着代码中的四步算子操作:
    源算子Source(socketTextStream())→扁平映射算子Flat Map(flatMap()) →分组聚合算子Keyed Aggregation(keyBy/sum()) →输出算子Sink(print())。
  2. 作业图(JobGraph)
    StreamGraph经过优化后生成的就是作业图(JobGraph),这是提交给 JobManager 的数据结构,确定了当前作业中所有任务的划分。主要的优化为: 将多个符合条件的节点链接在一起合并成一个任务节点,形成算子链,这样可以减少数据交换的消耗。JobGraph一般也是在客户端生成的,在作业提交时传递给JobMaster。

一个数据流在算子之间传输数据的形式可以是一对一(one-to-one)【map、filter、flatMap】的直通 (forwarding)模式,也可以是打乱的重分区(redistributing)模式

算子链:并行度相同的一对一(one to one)算子操作,可以直接链接在一起形成一个“大”的任务(task)【类似于spark中的窄依赖】

算子链接成task是非常有效的优化,可以减少线程之间的切换和基于缓存区的数据交换,在减少时延的同时提升吞吐量。

  1. 执行图(ExecutionGraph)
    JobMaster收到JobGraph后,会根据它来生成执行图(ExecutionGraph)。ExecutionGraph是JobGraph的并行化版本,是调度层最核心的数据结构。
    与JobGraph最大的区别就是按照并行度对并行子任务进行了拆分,并明确了任务间数据传输的方式。

从 DataStream API 到 StramGraph 的过程

DataStream

DataStream 的子类包括 SingleOutputStreamOperator、 DataStreamSource KeyedStream 、IterativeStream, SplitStream(已弃用)。

DataStream 与 StreamTransformation

每一个 DataStream 的底层都有对应的一个StreamTransformation。在 DataStream 上面通过 map 等算子不断进行转换,根据不同的操作生成不同的 StreamTransformation,并将其加入StreamExecutionEnvironment 的List<StreamTransformation<?>>transformations 来保留生成 DataStream 的所有转换。

StreamGraphGenerator 会基于 transformations 列表来生成 StreamGraph。
遍历 List生成 StreamGraph 的时候,会递归调用StreamGraphGenerator#transform方法。对于每一个 StreamTransformation, 确保当前其上游已经完成转换。StreamTransformations 被转换为 StreamGraph 中的节点 StreamNode,并为上下游节点添加边 StreamEdge。

StreamGraph 到 JobGraph 之间的转换过程

在 StreamGraph 中,每一个算子(Operator) 对应了图中的一个节点(StreamNode)
将多个符合条件的节点串联(Chain) 在一起形成一个节点,从而减少数据在不同节点之间流动所产生的序列化、反序列化、网络传输的开销。多个算子被 chain 在一起的形成的节点在 JobGraph 中对应的就是 JobVertex

JobGraph 的关键在于将多个 StreamNode 优化为一个 JobVertex, 对应的 StreamEdge 则转化为 JobEdge, 并且 JobVertex 和 JobEdge 之间通过 IntermediateDataSet 形成一个生产者和消费者的连接关系。

JobEdge

在 StramGraph 中,StreamNode 之间是通过 StreamEdge 建立连接的。在 JobEdge 中,对应的是 JobEdge 。

StreamEdge 中同时保留了源节点和目标节点 (sourceId 和 targetId), JobEdge 中只有源节点信息。由于 JobVertex 中保存了所有输入的 JobEdge 的信息,因而同样可以在两个节点之间建立连接。更确切地说,JobEdge 是和节点的输出结果相关联的。

IntermediateDataSet

JobVertex 产生的数据被抽象为 IntermediateDataSet(中间数据集)。JobEdge 是和节点的输出结果相关联的,其实就是指可以把 JobEdge 看作是 IntermediateDataSet 的消费者,那么 JobVertex 自然就是生产者了。

从 StreamGraph 到 JobGraph

从 StreamGraph 到 JobGraph 的转换入口在StreamingJobGraphGenerator 中。

通过 DFS 遍历所有 StreamNode, 按照 chainable 的条件将可以串联的stream operator 放在同一个 operator chain 中。每一个 StreamNode 的配置信息都会被序列化到对应的 StreamConfig 中。

只有 operator chain 的头部节点会生成对应的 JobVertex ,一个 operator chain
的所有内部节点都会以序列化的形式写入头部节点的 CHAINED_TASK_CONFIG 配置项中。

每一个 operator chain 都会为所有的实际输出边创建对应的 JobEdge,并和 JobVertex 连接

ExecutionGraph 的生成

StreamGraph, JobGraph 这两个执行图都是在 client 端生成的,ExecutionGraph 是在 JobManager 中生成的。Client 向 JobManager 提交 JobGraph 后, JobManager 就会根据 JobGraph 来创建对应的 ExecutionGraph,并以此来调度任务。

ExecutionJobVertex

ExecutionGraph 中,节点对应的类是 ExecutionJobVertex

ExecutionVertex

ExexutionJobVertex 的成员变量中包含一个 ExecutionVertex 数组。
ExecutionVertex 是并行任务的一个子任务,算子的并行度是多少,那么就会有多少个 ExecutionVertex。

Execution

Execution 是对 ExecutionVertex 的一次执行,通过 ExecutionAttemptId 来唯一标识。

IntermediateResult

在 JobGraph 中用 IntermediateDataSet(中间数据集) 表示 JobVertex 的对外输出,一个 JobGraph 可能有 n(n >=0) 个输出。在 ExecutionGraph 中,与此对应的就是 IntermediateResult。

ExecutionEdge

ExecutionEdge 表示 ExecutionVertex 的输入,通过 ExecutionEdge 将 ExecutionVertex 和 IntermediateResultPartition 连接起来,进而在不同的 ExecutionVertex 之间建立联系。

构建 ExecutionGraph 的流程

创建 ExecutionGraph 的入口在 ExecutionGraphBuilder#buildGraph() 中。

  • 每一个 JobVertex 对应一个 ExecutionJobVertex,
  • 每一个 ExecutionJobVertex 有parallelism 个 ExecutionVertex
  • 每一个 JobVertex 可能有 n(n>=0) 个IntermediateDataSet,ExecutionJobVertex 中,一个 IntermediateDataSet对应一个 IntermediateResult,
  • 每一个 IntermediateResult 都有 parallelism 个生产者,对应 parallelism 个IntermediateResultPartition
  • 每一个 ExecutionJobVertex都会和前向的 IntermediateResult 连接,实际上是 ExecutionVertex 和IntermediateResult 建立连接,生成 ExecutionEdge

Summary:
streamGraph 是最原始的,更贴近用户逻辑的 DAG 执行图;JobGraph 是对 StreamGraph 的进一步优化,将能够合并的算子合并为一个节点以降低运行时数据传输的开销;ExecutionGraph 则是作业运行是用来调度的执行图,可以看作是并行化版本的 JobGraph,将 DAG 拆分到基本的调度单元。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值