0


Flink 调度源码分析1:拓扑图创建与提交过程

Flink 调度源码分析1:拓扑图创建与提交过程
Flink 调度源码分析2:调度过程
Flink 调度源码分析3:Slot 分配策略

Flink 分配任务到物理设备上(静态资源分配)过程中,需要将用户代码进行下面的转换:StreamGraph -> JobGraph -> ExecutionGraph -> 物理执行图

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

在这里插入图片描述
以下是调度的一些步骤的分析。

1. 生成 StreamGraph

StreamGraph 是在 Client 端生成的。

  • Transformation:可查看 flink-streaming-java 模块中 org.apache.flink.streaming.api.transformations 下的类,有各种类型的 Transformation。
  • 算子将用户逻辑封装,并构造出 Transformation,然后将 Transformation 存储到 StreamExecutionEnvironment:// 将 Transformation 存储到执行环境中getExecutionEnvironment().addOperator(resultTransform);
  • 当调用 env.execute() 时,遍历执行环境中的 Transformation 集合,然后使用 StreamGraphGenerator.generate() 创建 StreamGraph。StreamGraph streamGraph =getStreamGraph();->finalStreamGraph streamGraph =getStreamGraph(transformations);->getStreamGraphGenerator(transformations).generate();->for(Transformation<?> transformation : transformations){transform(transformation);}// 记录slot共享组及其相应的细粒度资源档案 streamGraph.setSlotSharingGroupResource(slotSharingGroupResources);for(StreamNode node : streamGraph.getStreamNodes()){if(node.getInEdges().stream().anyMatch(this::shouldDisableUnalignedCheckpointing)){for(StreamEdge edge : node.getInEdges()){ edge.setSupportsUnalignedCheckpoints(false);}}}

注:并不是每一个 StreamTransformation 都会转换成 runtime 层中物理操作。有一些只是逻辑概念,比如 union、split/select、partition等。

2. 生成 JobGraph

JobGraph 是在 Client 端生成的。
该部分代码主要在 flink-runtime 模块中的,该过程主要在 org.apache.flink.runtime.jobgraph包中。StreamingJobGraphGenerator.createJobGraph() 中实现。

  • StreamNode 转成 JobVertex,将 one-to-one 且并行的相同的节点合并为一个节点。StreamEdge 转成 JobEdge。会为所有节点生成一个唯一的 hash id,如果节点在多次提交中没有改变(包括并发度、上下游等),那么这个 id 就不会改变,这主要用于故障恢复。

3. 集群接收并处理 JobGraph

这部分实现在 flink-runtime 模块中的 org.apache.flink.runtime.rest.handler.job.JobSubmitHandler.handleRequest() 方法中。在该方法中,会获取 restClient 的文件,获取 JobGraph 和对应的依赖、jar包,然后通过 dispatchergateway 提交 JobGraph。
下面代码负责继续处理 JobGraph。

CompletableFuture<Acknowledge> jobSubmissionFuture =  
        finalizedJobGraphFuture.thenCompose(  
                jobGraph -> gateway.submitJob(jobGraph, timeout));

可进而查看其调用的方法,如下所示。

gateway.submitJob(jobGraph, timeout)->internalSubmitJob(jobGraph)->this::persistAndRunJob->runJob(createJobMasterRunner(jobGraph),ExecutionType.SUBMISSION)

在 runJob() 中会创建 JobMaster,然后 JobGraph 在 JobMaster 中会被转化成 ExecutionGraph。

4. 生成 ExecutionGraph

Client 会将 JobGraph 进行提交,然后服务端会接收 JobGraph,创建 JobMaster,并将 JobGraph 转换为 ExecutionGraph。

  • 集群会在创建调度器时,创建 ExecutionGraph。调度器会继承 SchedulerBase 类,在该类的构造函数中通过下面的代码创建 ExecutionGraph。this.executionGraph =createAndRestoreExecutionGraph( completedCheckpointStore, checkpointsCleaner, checkpointIdCounter, initializationTimestamp, mainThreadExecutor, jobStatusListener, vertexParallelismStore); 查看其调用过程如下。createAndRestoreExecutionGraph(...)->finalExecutionGraph newExecutionGraph = executionGraphFactory.createAndRestoreExecutionGraph(...)->finalExecutionGraph newExecutionGraph =DefaultExecutionGraphBuilder.buildGraph(...)
  • JobManager 会根据 JobGraph 生成对应的 ExecutionGraph。ExecutionGraph 需要根据并行度将每个算子创建 ExecutionGraph,每个 ExecutionGraph 对应一个实例。该功能主要实现在 flink-runtime 模块中的 org.apache.flink.runtime.executiongraph.DefaultExecutionGraphBuilder.buildGraph() 方法中。该方法的部分代码如下:// 创建一个执行图 finalDefaultExecutionGraph executionGraph =newDefaultExecutionGraph(......);// 设置执行图的作业名、节点等信息 try{ executionGraph.setJsonPlan(JsonPlanGenerator.generatePlan(jobGraph));}catch(Throwable t){......}......// 创建节点for(JobVertex vertex : jobGraph.getVertices()){try{ vertex.initializeOnMaster(newSimpleInitializeOnMasterContext( classLoader, vertexParallelismStore .getParallelismInfo(vertex.getID()).getParallelism()));}catch(Throwable t){......}}// topologically sort the job vertices and attach the graph to the existing one List<JobVertex> sortedTopology = jobGraph.getVerticesSortedTopologicallyFromSources();// 生成执行图executionGraph.attachJobGraph(sortedTopology, jobManagerJobMetricGroup);

本文转载自: https://blog.csdn.net/White_Ink_/article/details/136873032
版权归原作者 北_鱼 所有, 如有侵权,请联系我们删除。

“Flink 调度源码分析1:拓扑图创建与提交过程”的评论:

还没有评论