spark源码学习(四):Resultstage的产生和submitstage提交

                 spark源码学习(四):Resultstage的产生和submitstage提交


      上次我们对于stage的划分没有详细的划分,这里就来看看这些stage到底是通过什么流程来实现的。稍微的说一下,这次的程序进入的接口是从上次的Onreceive方法进入的。由里面的JobSubmitted模式来匹配。进入这个方法来分析具体的流程操作。首先进入JobSubmitted方法:


       这里首先会创建一个newResultStage,作为finalStage,这里的finalStage代表的是上一blog的那个最后一个stage即为resultStage,resultStage的上一个就是shuffleMapStage,wordcount代码也就只有这两个Stage.这里我们明确在spark中的stage的创建是从后往前根据依赖的类型进行创建。newResultStage的代码创建如下:

spark源码学习(四):Resultstage的产生和submitstage提交_第1张图片

        上面代码中最重要的也就是getParentStageAndId,他主要是以当前的rdd也就是pairRddFunction和jobid作为参数,返回一个元组(parentStage,id),前面的代表这个当前的resultStage所依赖的全部stage,后面的就是返回当前stage的id,哈哈,具体就进入代码来看看吧:


         感觉不是很明确吧,怎么还有一个方法呢?那就继续进入getParentStage来看看:

private def getParentStages(rdd: RDD[_], jobId: Int): List[Stage] = {
    val parents = new HashSet[Stage]
    val visited = new HashSet[RDD[_]]
    //用一个栈来维护依赖的RDD,这些RDD都是所对应的非shufflDependency
    val waitingForVisit = new Stack[RDD[_]]
    def visit(r: RDD[_]) {
      if (!visited(r)) {
        visited += r
        for (dep <- r.dependencies) {
          dep match {//这里的模式匹配是核心
            case shufDep: ShuffleDependency[_, _, _] =>
              parents += getShuffleMapStage(shufDep, jobId)
            case _ =>
              waitingForVisit.push(dep.rdd)
          }
        }
      }
    }
    waitingForVisit.push(rdd)
    while (waitingForVisit.nonEmpty) {
      visit(waitingForVisit.pop())
    }
    parents.toList
  }
         我们可以看到:如果是ShuffleDependency就添加到parents里面,如果是窄依赖的话就把当前的rdd压入栈底,然后就pop这个rdd,判断他的dependency是什么依赖。最后把parents转化成list。至于上面的nextStageId很简单,他就是一个整形数字而已:new AtomicInteger(0).简单吧。stageIdToStage(id) = stage就是把对应的id设置成为对应的stage,最后在向当前的job注册当前的stage,毕竟job是需要stage进行一系列的计算的嘛。

      我们还要注意一下,在创建一个stage的时候,newResultStage里面的numTasks个数必须提前知道,因为要知道stage需要从多少个Partitions读取数据,直接影响创建多少个Task.

      stage创建相关的代码结束,下面来看看和jActivejob相关的:



       在源代码整体来看,jobId是体检就有的,但是真正看到newJob的地方确实是在这里。jobId的创建就是如下:

nextJobId = new AtomicInteger(0) jobId = nextJobId.getAndIncrement()。我也不明白为啥这样呢?看看activeJob:

spark源码学习(四):Resultstage的产生和submitstage提交_第2张图片

       然后下面的一些代码主要用于判断是否在本地执行,就不看了,看一下最重要的任务的提交submitStage函数

    

     进入submitStage函数来看看吧:

spark源码学习(四):Resultstage的产生和submitstage提交_第3张图片

      (1)首先来看看getMissingParentStages这个函数,主要是找到没有提交的父stage,并且保存在missing中

       (2) 然后在所有的stage都已经提交的情况下,调用submitMissingTasks才开始正儿八经的创建task,主要是根据依赖的类型来创建task,分为shuffleMapTask和resultTask两种任务。

       这里的两个函数都是重中之重,明儿再继续分析,睡觉。。。

     


你可能感兴趣的:(spark源码学习(四):Resultstage的产生和submitstage提交)