TaskScheduler是一个trait,这里以standalone模式下的TaskSchedulerImpl来分析。
上面文章最后说,DAGScheduler把stage中的task封装成TaskSet,调用TaskSchedulerImpl的submitTasks方法。
我们就从这个方法着手来分析TaskSchedulerImpl,这个方法可以理解为提交任务的入口。
override def submitTasks(taskSet: TaskSet) { val tasks = taskSet.tasks logInfo("Adding task set " + taskSet.id + " with " + tasks.length + " tasks") this.synchronized { //给每个taskSet都会创建一个TaskSetManager(在后面会负责它的那个taskSet的任务执行状况的监视和管理。在TaskSchedulerImpl 中,对一个单独的TaskSet任务进行调度。这个类负责追踪每一个task,如果task失败的话,会负责重试task,直到超过重试的次数限制 并且会通过延迟调度,为这个TaskSet处理本地化调度机制。他的主要接口是resourceOffer,在这个接口中,TaskSet会希望在一个节点 上运行一个任务,并且接受任务的状态改变消息,来直到它负责的task的状态改变了。) val manager = createTaskSetManager(taskSet, maxTaskFailures) val stage = taskSet.stageId val stageTaskSets = taskSetsByStageIdAndAttempt.getOrElseUpdate(stage, new HashMap[Int, TaskSetManager]) //加入内存缓存 stageTaskSets(taskSet.stageAttemptId) = manager val conflictingTaskSet = stageTaskSets.exists { case (_, ts) => ts.taskSet != taskSet && !ts.isZombie } if (conflictingTaskSet) { throw new IllegalStateException(s"more than one active taskSet for stage $