Spark源码分析之三:Stage划分

        继上篇《Spark源码分析之Job的调度模型与运行反馈》之后,我们继续来看第二阶段--Stage划分。

        Stage划分的大体流程如下图所示:


        前面提到,对于JobSubmitted事件,我们通过调用DAGScheduler的handleJobSubmitted()方法来处理。那么我们先来看下代码:

// 处理Job提交的函数
  private[scheduler] def handleJobSubmitted(jobId: Int,
      finalRDD: RDD[_],
      func: (TaskContext, Iterator[_]) => _,
      partitions: Array[Int],
      callSite: CallSite,
      listener: JobListener,
      properties: Properties) {
    var finalStage: ResultStage = null
    
    // 利用最后一个RDD(finalRDD),创建最后的stage对象:finalStage
    try {
      // New stage creation may throw an exception if, for example, jobs are run on a
      // HadoopRDD whose underlying HDFS files have been deleted.
      // 根据最后一个RDD获取最后的stage
      finalStage = newResultStage(finalRDD, func, partitions, jobId, callSite)
    } catch {
      case e: Exception =>
        logWarning("Creating new stage failed due to exception - job: " + jobId, e)
        listener.jobFailed(e)
        return
    }

    // 创建一个ActiveJob对象
    val job = new ActiveJob(jobId, finalStage, callSite, listener, properties)
    
    // 清除RDD分区位置缓存
    // private val cacheLocs = new HashMap[Int, IndexedSeq[Seq[TaskLocation]]]
    clearCacheLocs()
    
    // 调用logInfo()方法记录日志信息
    logInfo("Got job %s (%s) with %d output partitions".format(
      job.jobId, callSite.shortForm, partitions.length))
    logInfo("Final stage: " + finalStage + " (" + finalStage.name + ")")
    logInfo("Parents of final stage: " + finalStage.parents)
    logInfo("Missing parents: " + getMissingParentStages(finalStage))

    val jobSubmissionTime = clock.getTimeMillis()
    
    // 将jobId-->ActiveJob的对应关系添加到HashMap类型的数据结构jobIdToActiveJob中去
    jobIdToActiveJob(jobId) = job
    
    // 将ActiveJob添加到HashSet类型的数据结构activeJobs中去
    activeJobs += job
    
    finalStage.setActiveJob(job)
    
    //2 获取stageIds列表
    // jobIdToStageIds存储的是jobId--stageIds的对应关系
    // stageIds为HashSet[Int]类型的
    // jobIdToStageIds在上面newResultStage过程中已被处理
    val stageIds = jobIdToStageIds(jobId).toArray
    // stageIdToStage存储的是stageId-->Stage的对应关系
    val stageInfos = stageIds.flatMap(id => stageIdToStage.get(id).map(_.latestInfo))
    
    listenerBus.post(
      SparkListenerJobStart(job.jobId, jobSubmissionTime, stageInfos, properties))
    
    // 提交最后一个stage
    submitStage(finalStage)

    // 提交其他正在等待的stage
    submitWaitingStages()
  }
        这个handleJobSubmitted()方法一共做了这么几件事:

        第一,调用newResultStage()方法,生成Stage,包括最后一个Stage:ResultStage和前面的Parent Stage:ShuffleMapStage;

        第二,创建一个ActiveJob对象job;

        第三,清除RDD分区位置缓存;

        第四,调用logInfo()方法记录日志信息;

        第五,维护各种数据对应关系涉及到的数据结构:

        (1)将jobId-->ActiveJob的对应关系添加到HashMap类型的数据结构jobIdToActiveJob中去;

        (2)将ActiveJob添加到HashSet类型的数据结构activeJobs中去;

        第六,提交Stage;

        下面,除了提交Stage留在第三阶段外,我们挨个分析第二阶段的每一步。

        首先是调用newResultStage()方法,生成Stage,包括最后一个Stage:ResultStage和前面的Parent Stage:ShuffleMapStage。代码如下:

/**
   * Create a ResultStage associated with the provided jobId.
   * 用提供的jobId
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值