当某个task完成后,某个shuffle Stage X可能已完成,那么就可能会一些仅依赖Stage X的Stage现在可以执行了,所以要有响应task完成的状态更新流程。


=======================DAG task完成后的更新流程===================
->CoarseGrainedSchedulerBackend::receiveWithLogging  --调度器的事件接收器
->case StatusUpdate(executorId, taskId, state, data) --状态更新事件(来源于CoarseGrainedExecutorBackend)
->scheduler.statusUpdate(taskId, state, data.value) --状态更新
->taskResultGetter.enqueueSuccessfulTask(taskSet, tid, serializedData) --将成功的时间封装到一个executor排队执行
->getTaskResultExecutor.execute(new Runnable {override def run(): Unit = Utils.logUncaughtExceptions {
->val result = serializer.get().deserialize[TaskResult[_]](serializedData) match { --反序列化结果
->scheduler.handleSuccessfulTask(taskSetManager, tid, result) --处理成功的task
->taskSetManager.handleSuccessfulTask(tid, taskResult) 
-> sched.dagScheduler.taskEnded(tasks(index) ... result.metrics)  --另起一段
->maybeFinishTaskSet()  --判断是否taskSet结束了,更新状态。注意:在DAG里,调度的粒度是taskSet。
->sched.taskSetFinished(this)  --如果taskSet结束了,更新DAG的这个调度单元
->activeTaskSets -= manager.taskSet.id  --从active taskSet中删除tid
->manager.parent.removeSchedulable(manager) 
->schedulableQueue.remove(schedulable)  --从调度队列中删除tid
->schedulableNameToSchedulable.remove(schedulable.name)  --删除调度单元。
->makeOffers(executorId) --将这个executorId分配给其他task使用
  
->DAGScheduler::taskEnded  --任务结束事件处理流程
->eventProcessActor ! CompletionEvent(task, reason, result, accumUpdates, taskInfo, taskMetrics)
->def receive 
->case completion @ CompletionEvent(task, reason, _, _, taskInfo, taskMetrics) 
->dagScheduler.handleTaskCompletion(completion)  --Responds to a task finishing. 
//This is called inside the event loop so it assumes that it can modify the scheduler's internal state
->event.reason match => case Success =>  --task结果是成功的
->if (event.accumUpdates != null)   --如果是状态更新
->event.accumUpdates.foreach { case (id, partialValue)  --更新状态
->listenerBus.post(SparkListenerTaskEnd(...)) --通知listener任务结束
->stage.pendingTasks -= task  
->task match {
->case rt: ResultTask[_, _] =>  --如果是ResultTask
->if (job.numFinished == job.numPartitions)  --如果所有的分片数据都完成
->markStageAsFinished(stage) --那么这个Stage就是结束了
->runningStages -= stage --从running状态中删除
->listenerBus.post(SparkListenerStageCompleted(stage.latestInfo)) --通知Stage结束
->cleanupStateForJobAndIndependentStages(job) --清除依赖关系
->val registeredStages = jobIdToStageIds.get(job.jobId) --找到这个job对应的所有Stage(job对应多个stage)
->stageIdToStage.filterKeys(stageId => registeredStages.get.contains(stageId)).foreach 
//查找所有stage,找出注册了依赖于这个job所在stage的。
->case (stageId, stage) =>
->val jobSet = stage.jobIds  
->if (!jobSet.contains(job.jobId)) --这些存在依赖的stage中,应该包含这个job的注册
->logError("Job %d not registered for stage %d even though that stage was registered for the job"
  .format(job.jobId, stageId))
->if (jobSet.isEmpty)  // no other job needs this stage 没有其他job了,这个依赖的stage也结束了。
-> removeStage(stageId) --删除stage
->listenerBus.post(SparkListenerJobEnd(job.jobId, JobSucceeded)) --通知job结束
->job.listener.taskSucceeded(rt.outputId, event.result) --通知task成功
->case smt: ShuffleMapTask =>  --如果是shuffleMapTask
->if (runningStages.contains(stage) && stage.pendingTasks.isEmpty) --如果stage的所有task都完成
->markStageAsFinished(stage) --标志stage完成
->listenerBus.post(SparkListenerStageCompleted(stage.latestInfo)) --通知stage完成
->logInfo("looking for newly runnable stages") --stage完成了,意味着依赖这个stage的stage可以执行了
->mapOutputTracker.registerMapOutputs --(?用处不明)
->clearCacheLocs()
->if (stage.outputLocs.exists(_ == Nil)) // Some tasks had failed; let's resubmit this stage
->submitStage(stage)
->else
->val newlyRunnable = new ArrayBuffer[Stage]
-> for (stage <- waitingStages if getMissingParentStages(stage) == Nil) 如果一个stage没有依赖其他stage
->newlyRunnable += stage --这个没有依赖的stage就可以执行了
->waitingStages --= newlyRunnable
->runningStages ++= newlyRunnable
->for {stage <- newlyRunnable.sortBy(_.id); jobId <- activeJobForStage(stage)}
->submitMissingTasks(stage, jobId) --将这些没有依赖的stage的所有active job提交执行
->submitWaitingStages() --//Check for waiting or failed stages which are now eligible for resubmission.
//Ordinarily run on every iteration of the event loop. 每个事件处理都会触发去检查waiting状态的stage是否能够执行了。
->logTrace("Checking for newly runnable parent stages")
->waitingStages.clear()
    ->for (stage <- waitingStagesCopy.sortBy(_.jobId)) 
          ->submitStage(stage)

========================end================================

spark 笔记 13: 再看DAGScheduler,stage状态更新流程的更多相关文章

  1. 线性代数笔记13——Ax=b的通解

    关于最简行阶梯矩阵和矩阵秩,可参考<线性代数笔记7——再看行列式与矩阵> 召唤一个方程Ax = b: 3个方程4个变量,方程组有无数解,现在要关注的是b1b2b3之间满足什么条件时方程组有 ...

  2. spark 笔记 15: ShuffleManager,shuffle map两端的stage/task的桥梁

    无论是Hadoop还是spark,shuffle操作都是决定其性能的重要因素.在不能减少shuffle的情况下,使用一个好的shuffle管理器也是优化性能的重要手段. ShuffleManager的 ...

  3. Android菜鸟的成长笔记(17)—— 再看Android中的Unbounded Service

    原文:Android菜鸟的成长笔记(17)-- 再看Android中的Unbounded Service 前面已经写过关于startService(Unbounded Service)的一篇文章:&l ...

  4. Spark源码分析之三:Stage划分

    继上篇<Spark源码分析之Job的调度模型与运行反馈>之后,我们继续来看第二阶段--Stage划分. Stage划分的大体流程如下图所示: 前面提到,对于JobSubmitted事件,我 ...

  5. spark作业运行过程之--DAGScheduler

    DAGScheduler--stage划分和创建以及stage的提交 本篇,我会从一次spark作业的运行为切入点,将spark运行过程中涉及到的各个步骤,包括DAG图的划分,任务集的创建,资源分配, ...

  6. spark 笔记 2: Resilient Distributed Datasets: A Fault-Tolerant Abstraction for In-Memory Cluster Computing

    http://www.cs.berkeley.edu/~matei/papers/2012/nsdi_spark.pdf  ucb关于spark的论文,对spark中核心组件RDD最原始.本质的理解, ...

  7. 【原】Spark中Job如何划分为Stage

    版权声明:本文为原创文章,未经允许不得转载. 复习内容: Spark中Job的提交 http://www.cnblogs.com/yourarebest/p/5342404.html 1.Spark中 ...

  8. 并发编程学习笔记(13)----ConcurrentLinkedQueue(非阻塞队列)和BlockingQueue(阻塞队列)原理

    · 在并发编程中,我们有时候会需要使用到线程安全的队列,而在Java中如果我们需要实现队列可以有两种方式,一种是阻塞式队列.另一种是非阻塞式的队列,阻塞式队列采用锁来实现,而非阻塞式队列则是采用cas ...

  9. spark笔记 环境配置

    spark笔记 spark简介 saprk 有六个核心组件: SparkCore.SparkSQL.SparkStreaming.StructedStreaming.MLlib,Graphx Spar ...

随机推荐

  1. Windows7/win10系统安装JDK的环境变量设置javac不是内部命令或外部命令

    ---恢复内容开始--- Windows7/win10系统安装JDK的环境变量设置 Windows7 X64安装“jdk-6u26-windows-x64.exe”后,按照网上的环境变量设置方法设置了 ...

  2. postgres外部表

    在创建外部表的时候遇见: CREATE EXTENSION file_fdw;2018-12-21 17:32:23.822 CST [31237] ERROR:  could not open ex ...

  3. Spingboot项目的创建与启动(基于IDEA)

    一.Springboot的创建 1.Springboot的优点: Springboot是来简化Spring框架,从而能够更加简单快捷的构建Spring应用的框架,其具有如下优点: ①为所有Spring ...

  4. vs2017新建一个空项目

    我们会发现VS2017的控制台程序创建之后会有一些头文件这和之前的VS的版本不一样之前的都可以选择空项目来避免,下面我们就来介绍方法: 首先我们不要创建新的控制台项目,而是创建桌面向导: 然后我们就可 ...

  5. Codeforces Manthan, Codefest 18 (rated, Div. 1 + Div. 2) E.Trips

    比赛的时候想到怎么做了 没调出来(感觉自己是个睿智) 给你N个点M条边,这M条边是一条一条加进去的 要求你求出加入每一条边时图中极大'K度'子图的大小 极大'K度'子图的意思是 要求出一个有尽量多的点 ...

  6. hadoop常见命令

    常用命令 启动Hadoop 进入HADOOP_HOME目录. 执行sh bin/start-all.sh 关闭Hadoop 进入HADOOP_HOME目录. 执行sh bin/stop-all.sh ...

  7. JavaScript入门学习之一——初级语法

    JavaScript是前端编辑的一种编程语言(不同于html,html是一种标记语言),所以和其他的编程语言一样,我们将会从下面几点学习 基础语法 数据类型 函数 面向对象 JavaScript的组成 ...

  8. 手摸手带你实现 小游戏<别踩白块儿 -- 内有游戏链接>

    别踩白块儿 使用(白鹭引擎)Egret编写的游戏 游戏地址 准备工作 了解白鹭引擎 并安装编写工具 安装游戏引擎 安装Egret Wing3 创建项目 创建项目可以选择不同版本的引擎,创建成功之后还可 ...

  9. re模块的小练习

    1.匹配标签 1 import re 2 ret = re.search('<(?P<tag_name>\w+)>\w+</(?P=tag_name)>','< ...

  10. Mycat常见问题与解决方案

    转载于:https://www.cnblogs.com/jpfss/p/8194111.html 1 Mycat目前有哪些功能与特性? 答:• 支持 SQL 92标准• 支持Mysql集群,可以作为P ...