Spark1.6.3 Driver端 task运行完成源码分析

原创 2017年01月03日 11:04:30
0.背景
0.1当完成task调度:
Executor就会收到serialized的 task,先deserialize 出正常的task,然后运行task得到结果,并通过状态更新的RPC告知SchedulerBackend
0.2这里主要分析GoarseGrainedSchedulerBackend.scala的情况



1.GoarseGrainedSchedulerBackend.scala 接收task完成信息

1.1 receive()函数:
接收到StatusUpdate(executorId, taskId, state, data)事件后,会把这个事件继续转到taskSchedulerImpl,调用scheduler.statusUpdate(taskId, state, data.value).
1.2 参数:
(1) state表示task的状态,这里主要讨论FINISHED的情况,如果task完成,就会运行makeOffers(executorId)继续调度剩余的task。
(2) data表示executor端传递过来的serializedData。



2.TaskSchedulerImpl.scala 初步接收task完成信息

具体分析statusUpdate(tid, state, serializedData):
2.1 taskIdToTaskSerManager.get(tid) match {......}
根据taskId推出它所属于的taskSetManager
2.2 taskSet.removeRunningTask(tid)
      taskResultGetter.enqueueSuccessfulTask(taskSet, tid, serializedData)
更新相关数据结构,然后使用taskResultGetter对serializedData进行反序列化



3.taskResultGetter.scala 反序列化task结果

具体分析enqueueSuccessfulTask(taskSetManager, tid, serializedData)
3.1 val (result, size) = serializer.get().deserialized[TaskResult[_]](serializedData) match{......}
调用serializer将serializedData进行反序列化,这里分两种情况,说明如下:当 task在Executor端完成后会返回其执行结果 result,并且这个结果要荣国Actor发送到driver端。但Actor发送的数据包不宜过大,因此:
(1) 当result不大时,serializedData保存的直接序列化的结果,也就是 case directResult: DirectTaskResult[_] =>,最后直接获得(directResult, serializedData.limit())
(2) 如果 result 比较大, serializedData保存的是结果存储位置blockId和结果大小size,也就是 case IndirectTaskResult(blockId, size),然后driver端会调用sparkEnv.blockManager.getRemoteBytes(blockId)通过HTTP的方式去获取serializedTaskResult,再进行第二次反序列化获得deserializedResult, 最后获得(deserializedResult, size).
3.2 scheduler.handleSuccessfulTask(taskSetManager, tid, result)
经过taskResultGetter.scala的反序列化后在回到TaskSchedulerImpl.scala



4.TaskSchedulerImpl.scala 再次接收task完成信息

taskSetManager.handleSuccessfulTask(tid, taskResult)将把task完成信息送到所属的TaskSetManager中进行处理



5.TaskSetManager.scala 接收task完成信息

具体分析handleSuccessfulTask(tid, result)
5.1 val info = taskIndos(tid) ...... removeRunningTask(tid):
更新task相关数据结构
5.2 sched.dagScheduler.taskEnded(......)
将task完成的信息告知dagScheduler
5.3 if(!successful(index)) {......}
更新有关taskSet完成的数据结构
5.4 maybeFinishTaskSet()
判断taskSet是否以及完成,如果完成则调用sched.taskSetFinished(this),来告知上层的taskSchedulerImpl.scala



6.TaskSchedulerImpl.scala 接收taskSet完成信息(optional)


首先更新管理taskSets的数据结构taskSetsByStageIdAndAttempt, 然后调用manager.parent.removeSchedulable(manger)将这个taskSet从调度池中删除



7.DAGScheduler.scala 接收task完成信息

7.1 eventProcessloop:
会post出一个CompletionEvent的事件,这个事件会被DAGScheduler.scala中的doOnReveive接受并处理,然后调用dagScheduler.handleTaskCompletion(completion)

。。。。。。

7.2 分析dagScheduler.handleTaskCompletion(completion)
(1) case Success => 
          ListenerBus.post(SparkListenerTaskEnd(......))
向ListenerBus上广播taskEnd的事件,按需被接收,关于ListenerBus有待后续分析
(2) stage.pendingPartitons -= task.partitionId
task的完成表示stage最后阶段RDD的一个partition已经获得,因此更新数据结构
(3) task match {
     case rt: ResultTask[_, _] => 
     .......
     markStageAsFinished(resultStage)
     cleanupStageForJobAndIndependentStage(job)
     ListenerBus.post(SparkListenerJobEnd)
如果task是ResultTask,会判断所属Job是否完成,如果完成,首先调用markStageAsFinished来post相关stage完成事件,具体实现为内部的ListenerBus.post(SparkListenerStageCompleted(......));然后调用cleanupStageForJobAndIndependentStage并根据是否有其他job需要这个stage来更新相关数据结构,主要有jobIdToStageIds和stageIdToStage;最后post出job完成的事件
(4) case smt: ShuffleMapTask =>
和上面类似,只是没有post出job完成的事件



8.画图总结

版权声明:本文为博主原创文章,未经博主允许不得转载。

Spark源码分析之七:Task运行(一)

在Task调度相关的两篇文章《Spark源码分析之五:Task调度(一)》与《Spark源码分析之六:Task调度(二)》中,我们大致了解了Task调度相关的主要逻辑,并且在Task调度逻辑的最后,C...
  • lipeng_bigdata
  • lipeng_bigdata
  • 2016年02月24日 23:43
  • 5331

spark 数据倾斜问题

先上两张大图压压惊:   Driver拒绝提交任务: 16/11/07 10:31:50 INFO OutputCommitCoordinator: Task was denied comm...
  • fjr_huoniao
  • fjr_huoniao
  • 2016年11月09日 14:57
  • 1267

大数据:Spark Core(二)Driver上的Task的生成、分配、调度

1. 什么是Task? 在前面的章节里描述过几个角色,Driver(Client),Master,Worker(Executor),Driver会提交Application到Master进行Work...
  • raintungli
  • raintungli
  • 2017年04月14日 09:21
  • 4099

网络原因造成 spark task 卡住

主机名映射出错背景:Yarn集群新加入了一批Spark机器后发现运行Spark任务时,一些task会无限卡住且driver端没有任何提示。解决:进入task卡住的节点查看container stder...
  • lsshlsw
  • lsshlsw
  • 2017年05月10日 00:36
  • 1001

Spark Streaming 流计算优化记录(4)-时间都去哪儿了,关于调度与空转

关于Spark Streaming优化的各种叽里呱啦记录, 这一次是从跑不动, 一直优化到能每秒解决6万条输入消息以及3G数据的Inner Join. 大数据,流计算,spark,kafka,hado...
  • butterluo
  • butterluo
  • 2015年07月27日 14:17
  • 1742

Hive on Spark源码分析(一)—— SparkTask

之所以首先分析SparkTask的源码的原因,是根据Hive on Spark的运行模式和任务提交流程的出来的。首先我们看一下Hive on Spark运行模式:        Hive on Spa...
  • Camu7s
  • Camu7s
  • 2016年08月17日 00:52
  • 1390

37 Spark之Task执行原理及结果

第三十七课 Spark之Task执行原理及结果 主要内容 1. Task执行原理流程图 2. Task执行源码 3. Task执行结果在Driver端的处理...
  • sinat_25306771
  • sinat_25306771
  • 2016年05月19日 10:43
  • 10682

Spark Streaming性能调优详解

Spark Streaming提供了高效便捷的流式处理模式,但是在有些场景下,使用默认的配置达不到最优,甚至无法实时处理来自外部的数据,这时候我们就需要对默认的配置进行相关的修改。由于现实中场景和数据...
  • DF_XIAO
  • DF_XIAO
  • 2016年01月28日 14:16
  • 738

Spark的几个基本概念:Driver和Job,Stage

Driver Program, Job和Stage是Spark中的几个基本概念。Spark官方文档中对于这几个概念的解释比较简单,对于初学者很难正确理解他们的涵义。官方解释如下(http://spar...
  • jiangwlee
  • jiangwlee
  • 2016年03月01日 18:05
  • 12146

Spar学习3:Spark运行概览

Spark核心程序概念
  • yunlong34574
  • yunlong34574
  • 2014年09月06日 20:22
  • 13121
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Spark1.6.3 Driver端 task运行完成源码分析
举报原因:
原因补充:

(最多只允许输入30个字)