Spark Runtime里的主要层次分析,梳理Runtime组件和执行流程,
DAGScheduler
Job=多个stage,Stage=多个同种task, Task分为ShuffleMapTask和ResultTask,Dependency分为ShuffleDependency和NarrowDependency
面向stage的切分,切分依据为宽依赖
维护waiting jobs和active jobs,维护waiting stages、active stages和failed stages,以及与jobs的映射关系
主要职能
- 接收提交Job的主入口,
submitJob(rdd, ...)
或runJob(rdd, ...)
。在SparkContext
里会调用这两个方法。
- 生成一个Stage并提交,接着判断Stage是否有父Stage未完成,若有,提交并等待父Stage,以此类推。结果是:DAGScheduler里增加了一些waiting stage和一个running stage。
- running stage提交后,分析stage里Task的类型,生成一个Task描述,即TaskSet。
- 调用
TaskScheduler.submitTask(taskSet, ...)
方法,把Task描述提交给TaskScheduler。TaskScheduler依据资源量和触发分配条件,会为这个TaskSet分配资源并触发执行。 DAGScheduler
提交job后,异步返回JobWaiter
对象,能够返回job运行状态,能够cancel job,执行成功后会处理并返回结果
- 处理
TaskCompletionEvent
- 如果task执行成功,对应的stage里减去这个task,做一些计数工作:
- 如果task是ResultTask,计数器
Accumulator
加一,在job里为该task置true,job finish总数加一。加完后如果finish数目与partition数目相等,说明这个stage完成了,标记stage完成,从running stages里减去这个stage,做一些stage移除的清理工作 - 如果task是ShuffleMapTask,计数器
Accumulator
加一,在stage里加上一个output location,里面是一个MapStatus
类。MapStatus
是ShuffleMapTask
执行完成的返回,包含location信息和block size(可以选择压缩或未压缩)。同时检查该stage完成,向MapOutputTracker
注册本stage里的shuffleId和location信息。然后检查stage的output location里是否存在空,若存在空,说明一些task失败了,整个stage重新提交;否则,继续从waiting stages里提交下一个需要做的stage
- 如果task是ResultTask,计数器
- 如果task是重提交,对应的stage里增加这个task
- 如果task是fetch失败,马上标记对应的stage完成,从running stages里减去。如果不允许retry,abort整个stage;否则,重新提交整个stage。另外,把这个fetch相关的location和map任务信息,从stage里剔除,从
MapOutputTracker
注销掉。最后,如果这次fetch的blockManagerId对象不为空,做一次ExecutorLost
处
- 如果task执行成功,对应的stage里减去这个task,做一些计数工作: