文章目录
由于在实际开发中都是使用yarn-cluster模式,所以本文也以该模式为分析的前提。
1. 相关概念
首先明确几个在任务调度方面的常用概念:
(1)Job 是以 Action 算子为界,遇到一个Action算子则触发一个Job;
(2)Stage 是 Job 的子集,以 RDD 宽依赖(即 Shuffle )为界,遇到 Shuffle 做一次划分;
(3)Task 是 Stage 的子集,以并行度(分区数)来衡量,这个 Stage 分区数是多少,则这个Stage 就有多少个 Task。
另外在任务调度过程中,有两个非常重要的调度器:DAGScheduler和TaskScheduler。
(1)DAGScheduler负责Stage级的调度,主要是将job切分成若干Stages,并将每个Stage打包成TaskSet交给TaskScheduler调度。
(2)TaskScheduler负责Task级的调度,将DAGScheduler传过来的TaskSet按照指定的调度策略分发到Executor上执行,调度过程中SchedulerBackend负责提供可用资源,其中SchedulerBackend有多种实现,分别对接不同的资源管理系统。
2. 任务调度
接下来我们来具体分析一下Spark的任务调度流程:
2.1 Stage级别任务调度:
概略来说涉及到以下方法:
以下是基于源码执行流程的具体分析:
(1)Job 由最终的RDD和Action方法封装而成;
(2)SparkContext将Job交给DAGScheduler提交,它会根据RDD的血缘关系构成的DAG进行切分,将一个Job划分为若干Stages,具体划分策略是,由最终的RDD不断通过依赖回溯判断父依赖是否是宽依赖,即以