def collect(): Array[T] = withScope {
//這里的this是當(dāng)前rdd(調(diào)用action算子的rdd),后面會(huì)有傳遞
val results = sc.runJob(this, (iter: Iterator[T]) => iter.toArray)
Array.concat(results: _*)
}
//這里的this是當(dāng)前rdd(調(diào)用action算子的rdd),后面會(huì)有傳遞
dagScheduler.runJob(rdd, cleanedFunc, partitions, callSite, resultHandler, localProperties.get)
eventProcessLoop POST JobSubmitted 事件
eventProcessLoop.post(JobSubmitted(
//這里的this是當(dāng)前rdd(調(diào)用action算子的rdd)婚温,后面會(huì)有傳遞
jobId, rdd, func2, rdd.partitions.indices.toArray, callSite, listener,
clonedProperties))
listener.awaitResult()
eventThread 消費(fèi)事件進(jìn)行處理
private[spark] val eventThread = new Thread(name) {
override def run(): Unit = {
try {
while (!stopped.get) {
val event = eventQueue.take()
try {
onReceive(event)
... ...
}
}
}
doOnReceive
private def doOnReceive(event: DAGSchedulerEvent): Unit = event match {
case JobSubmitted(jobId, rdd, func, partitions, callSite, listener, properties) =>
dagScheduler.handleJobSubmitted(jobId, rdd, func, partitions, callSite, listener, properties)
DAGScheduler.handleJobSubmitted 核心代碼
private[scheduler] def handleJobSubmitted(jobId: Int,
finalRDD: RDD[_],
func: (TaskContext, Iterator[_]) => _,
partitions: Array[Int],
callSite: CallSite,
listener: JobListener,
properties: Properties): Unit = {
var finalStage: ResultStage = null
try {
//創(chuàng)建ResultStage
finalStage = createResultStage(finalRDD, func, partitions, jobId, callSite)
DAGScheduler.createResultStage
private def createResultStage(
rdd: RDD[_],
func: (TaskContext, Iterator[_]) => _,
partitions: Array[Int],
jobId: Int,
callSite: CallSite): ResultStage = {
val (shuffleDeps, resourceProfiles) =
//獲取rdd 的ShuffleDependencies
getShuffleDependenciesAndResourceProfiles(rdd)
... ...
//創(chuàng)建parent stage
val parents = getOrCreateParentStages(shuffleDeps, jobId)
val id = nextStageId.getAndIncrement()
//創(chuàng)建ResultStage,//這里的rdd(調(diào)用action算子的rdd)
val stage = new ResultStage(id, rdd, func, partitions, parents, jobId,
callSite, resourceProfile.id)
... ...
stage
}
private[scheduler] def getShuffleDependenciesAndResourceProfiles(
rdd: RDD[_]): (HashSet[ShuffleDependency[_, _, _]], HashSet[ResourceProfile]) = {
val parents = new HashSet[ShuffleDependency[_, _, _]]
val resourceProfiles = new HashSet[ResourceProfile]
val visited = new HashSet[RDD[_]]
val waitingForVisit = new ListBuffer[RDD[_]]
waitingForVisit += rdd
while (waitingForVisit.nonEmpty) {
val toVisit = waitingForVisit.remove(0)
if (!visited(toVisit)) {
visited += toVisit
Option(toVisit.getResourceProfile).foreach(resourceProfiles += _)
toVisit.dependencies.foreach {
//如果rdd的Dependency 是ShuffleDependency類型就放入Dependencies返回
case shuffleDep: ShuffleDependency[_, _, _] =>
parents += shuffleDep
case dependency =>
waitingForVisit.prepend(dependency.rdd)
}
}
}
(parents, resourceProfiles)
}
DAGScheduler.getOrCreateParentStages
private def getOrCreateParentStages(shuffleDeps: HashSet[ShuffleDependency[_, _, _]],
firstJobId: Int): List[Stage] = {
//遍歷shuffleDeps 對(duì)每一個(gè)shuffleDep創(chuàng)建ShuffleMapStage
.map { shuffleDep =>
getOrCreateShuffleMapStage(shuffleDep, firstJobId)
}.toList
}
DAGScheduler.createShuffleMapStage
def createShuffleMapStage[K, V, C](
shuffleDep: ShuffleDependency[K, V, C], jobId: Int): ShuffleMapStage = {
val rdd = shuffleDep.rdd
val (shuffleDeps, resourceProfiles) = getShuffleDependenciesAndResourceProfiles(rdd)
... ...
val numTasks = rdd.partitions.length
//創(chuàng)建依賴的parent stage
val parents = getOrCreateParentStages(shuffleDeps, jobId)
val id = nextStageId.getAndIncrement()
//穿建mapstage
val stage = new ShuffleMapStage(
id, rdd, numTasks, parents, jobId, rdd.creationSite, shuffleDep, mapOutputTracker,
resourceProfile.id)
stageIdToStage(id) = stage
... ...
}
stage
}