DAGScheduler任务调度剖析

本文深入剖析了Spark的DAGScheduler的主要功能,包括job的stage划分、任务的首选位置决策、面向stage的调度策略以及stage输出的追踪。在stage划分部分,详细介绍了创建Stage的过程;任务的首选位置决策则在submitMissingTasks方法中得以体现;DAGScheduler不负责具体task调度,而是将任务提交给TaskScheduler。此外,DAGScheduler还需关注ShuffleMapStage的输出,以便优化调度,并在必要时重新提交stage。
摘要由CSDN通过智能技术生成

一、主要功能

  • 对每个job划分stage
  • 决定任务运行的首选位置(preferred locations)
  • 面向stage进行任务调度
  • 跟踪stage的输出
  • 需要时重新提交stage

二、主要功能的展开描述

1、怎么划分stage?

先看这个数据结构,stage划分之后保存在一个HashMap中,stageId作为key,Stage对象作为value

private[scheduler] val stageIdToStage = new HashMap[Int, Stage]

spark在任务提交时才划分stage,我们可以根据任务提交调用栈链条来找到线索跟踪job提交流程我们追踪到handleJobSubmitted

finalStage = createResultStage(finalRDD, func, partitions, jobId, callSite)

我们具体看下createResultStage

  private def createResultStage(
      rdd: RDD[_],
      func: (TaskContext, Iterator[_]) => _,
      partitions: Array[Int],
      jobId: Int,
      callSite: CallSite): ResultStage = {
    ......
    //这里创建祖先stage,这说明stage是根据最终RDD,逐级往源头回溯创建stage,可以看到主要的创建过程就在这里
    val parents = getOrCreateParentStages(rdd, jobId)
    val id = nextStageId.getAndIncrement()
    val stage = new ResultStage(id, rdd, func, partitions, parents, jobId, callSite)
    stageIdToStage(id) = stage
    updateJobIdStageIdMaps(jobId, stage)
    stage
  }

接下来

// 返回 List[Stage] ,这一步操作将祖先stage全部创建完成
private def getOrCreateParentStages(rdd: RDD[_], firstJobId: Int): List[Stage] = {
// 这里也就容易理解是按照宽依赖为界限划分stage,在为RDD的祖先RDD生成stage时,直接获取祖先的shuffle依赖,如果没有
shuffle依赖,那整个job就一个stage
    getShuffleDependencies(rdd).map { shuffleDep =>
    // 某个宽依赖的stage可能已经
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值