|NO.Z.00090|——————————|BigDataEnd|——|Hadoop&Spark.V06|——|Spark.v06|Spark 原理 源码|作业执行原理&Stage划分&handleJobSubmitted => createResultStage|
一、Stage划分
### --- handleJobSubmitted => createResultStage
~~~ # 源码提取说明:
~~~ # 440行~522行
private 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
分类:
bdv018-spark.v03
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通