|NO.Z.00090|——————————|BigDataEnd|——|Hadoop&Spark.V06|——|Spark.v06|Spark 原理 源码|作业执行原理&Stage划分&handleJobSubmitted => createResultStage|

一、Stage划分
### --- handleJobSubmitted => createResultStage

~~~     # 源码提取说明:
~~~     # 440行~522private def createResultStage(
     rdd: RDD[_],
     func: (TaskContext, Iterator[_]) => _,
     partitions: Array[Int],
     jobId: Int,
     callSite: CallSite): ResultStage = {
    /**
     * 获取所有父Stage的列表,父Stage主要是宽依赖(ShuffleDependency)对应的Stage,此列表内的Stage包含以下几种:
     * 1. 当前RDD的直接或间接的依赖是ShuffleDependency且已经注册过的Stage。
     * 2. 当前RDD的直接或间接的依赖是ShuffleDependency且没有注册过Stage的。
     * 对于这种ShuffleDependency,则根据ShuffleDependency中的RDD,
     * 找到它的直接或间接的依赖是ShuffleDependency且没有注册过Stage的所有ShuffleDependency,为它们创建并注册Stage。
     * 3. 当前RDD的直接或间接的依赖是ShuffleDependency且没有注册过Stage的。为此ShuffleDependency创建并注册Stage。
     */
    val parents = getOrCreateParentStages(rdd, jobId)
    // 生成ResultStage的身份标识
    val id = nextStageId.getAndIncrement()
    // 创建ResultStage对象
    val stage = new ResultStage(id, rdd, func, partitions, parents, jobId, callSite)
    // 记录Stage与stageId的映射
    stageIdToStage(id) = stage

    // 更新Job的身份标识与ResultStage及其所有祖先的映射关系
    updateJobIdStageIdMaps(jobId, stage)
    stage
  }
  // 获取给定RDD直接父类的 shuffle 依赖
  private def getOrCreateParentStages(rdd: RDD[_], firstJobId: Int): List[Stage] = {
    // 获取RDD的所有ShuffleDependency的序列
    getShuffleDependencies(rdd)
      // 逐个访问每个RDD及其依赖的非Shuffle的RDD
      .map { shuffleDep => 
        // 为每一个ShuffleDependency获取或者创建对应的ShuffleMapStage
        getOrCreateShuffleMapStage(shuffleDep, firstJobId)
      }.toList // 返回得到的ShuffleMapStage列表
  }
  // 获取RDD的所有ShuffleDependency的序列
  private[scheduler] def getShuffleDependencies(rdd: RDD[_]): HashSet[ShuffleDependency[_, _, _]] = {
    val parents = new HashSet[ShuffleDependency[_, _, _]]
    val visited = new HashSet[RDD[_]]
    val waitingForVisit = new Stack[RDD[_]]
    // 先将rdd压入waitingForVisit栈中
    waitingForVisit.push(rdd)
    // 当waitingForVisit栈不为空时
    while (waitingForVisit.nonEmpty) {
      // 弹出栈顶RDD
      val toVisit = waitingForVisit.pop()
      // 判断是否已经处理过
      if (!visited(toVisit)) { // 没有处理该RDD
        // 添加到已处理集合进行记录
        visited += toVisit
        // 遍历该栈顶RDD的所有依赖
        toVisit.dependencies.foreach {
          // 如果是ShuffleDependency,就将其记录到parents集合
          case shuffleDep: ShuffleDependency[_, _, _] => parents += shuffleDep
          // 如果是其他Dependency,就将该依赖的RDD压入到waitingForVisit栈中
          case dependency => waitingForVisit.push(dependency.rdd)
        }
      }
    }
    parents
  }

 
 
 
 
 
 
 
 
 

Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
                                                                                                                                                   ——W.S.Landor

 

 

posted on   yanqi_vip  阅读(24)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示