Spark2.3.2源码解析: 10. 调度系统 Task任务提交 (一) DAGScheduler 之 stage 提交

 

一个Spark Application分为stage级别和task级别的调度, 

task来源于stage,所有本文先从stage提交开始讲解task任务提交。

架构图:

Standalone模式提交运行流程图:

首先写一个WordCount代码(这个代码,为了观察多个suffle操作,我写了两个reducebykey 函数)

源代码:

直接执行代码,查看spark执行程序时,将代码划分stage生成的DAG流程图

可知: WordCount 在stage划分的时候,划分为三个stage 

即在代码中如下标识:

讲TaskScheduler ,先从DAGScheduler中提交任务开始吧,其中在stage划分task的时候,涉及到一些优化算法。

org.apache.spark.scheduler.DAGScheduler#handleMapStageSubmitted

这个方法主要有三个部分:

1、创建finalStage

finalStage = getOrCreateShuffleMapStage(dependency, jobId)
2、创建ActiveJob

val job = new ActiveJob(jobId, finalStage, callSite, listener, properties)
3.提交stage

submitStage(finalStage)

直接看第三步 submitStage

这个是提交stage方法。

里面是一个递归方法,举例:

在代码中, 划分为三个stage:

stage0  ---> stage1     ---> stage2

 submitStage(stage: Stage) 这个方法先传入的是 finalStage(stage2)

在方法里面循环递归, 分别寻找stage的父stage, 即 stage2 找到 stage1 , stage1找到stage0

stage0 没有父stage 即走 提交方法:

submitMissingTasks(stage: Stage, jobId: Int)

好,接下来,我们看submitMissingTasks

 

可以看到入参: ShuffleMapStage 0 和 jobId 0

 找出当前stage的所有分区中,还没计算完分区的stage

ShuffleMapStage

stage.findMissingPartitions获取需要计算的分区,不同的stage有不同的实现:

ResultStage

计算 分区的最佳位置 :  taskIdToLocations

计算最佳位置的核心方法: getPreferredLocsInternal  (递归方法)

这个开始传入的RDD:3,

rdd:3找不到最佳位置, 找到rdd:3的父级rdd:2,

rdd2,找不到最佳位置,找到rdd2的父级rdd1

rdd1有最佳位置,直接返回: 具体的机器地址:

广播信息:

为每一个MapStage的分区 创建一个 ShuffleMapTask 或者 ResultTask 

将ShuffleMapTask 或者 ResultTask  封装成taskSet,提交Task

在这里执行的是

taskScheduler.submitTasks(new TaskSet(
  tasks.toArray, stage.id, stage.latestInfo.attemptNumber, jobId, properties))

接着调用执行的是:

org.apache.spark.scheduler.TaskSchedulerImpl#submitTasks

未完,请看下一篇文章:

Spark2.3.2源码解析: 10. 调度系统 Task任务提交 (二) TaskScheduler ​​

https://blog.csdn.net/zhanglong_4444/article/details/85249376


 

猜你喜欢

转载自blog.csdn.net/zhanglong_4444/article/details/85201386
今日推荐