一、Spark 任务调度机制概述
在生产环境下,Spark 集群的部署方式一般为 YARN-Cluster 模式,下面内核分析中默认集群的部署方式为 YARN-Cluster 模式。
Driver 线程主要是初始化 SparkContext 对象,准备运行所需的上下文,然后一方面保持与 ApplicationMaster 的 RPC 连接,通过 ApplicationMaster 申请资源,另一方面根据用户业务逻辑开始调度任务,将任务下发到已有的空闲 Executor 上。
当 ResourceManager 向 ApplicationMaster 返回 Container 资源时,ApplicationMaster 就尝试在对应的 Container 上启动 Executor 进程,Executor 进程起来后,会向 Driver 反向注册,注册成功后保持与 Driver 的心跳,同时等待 Driver 分发任务,当分发的任务执行完毕后,将任务状态上报给 Driver。
二、Spark 任务调度介绍
当 Driver 起来后,Driver 则会根据用户程序逻辑准备任务,并根据 Executor 资源情况逐步分发任务。在介绍任务调度前面,说明一下 Spark 中的几个概念。一个 Spark 应用程序包括 Job、Stage 以及 Task 三个概念:
(1) Job 是以 Action 方法为界,遇到一个 Action 方法则触发一个 Job。
(2) Stage 是 Job 的子集,以 RDD 宽依赖(即 Shuffle)为界,遇到 Shuffle 做一次划分。
(3) Task 是 Stage 的子集,以并行度(分区数)来衡量,分区数是多少,则有多少个 task。
Spark 的任务调度总体来说是两路进行,一路是 Stage 级的调度,一路是 Task 级的调度,总体调度流程如下图:
Spark RDD 通过其 Transformation 操作,形成了 RDD 血缘(依赖) 关系图,即 DAG,最后通过 Action 的调用,触发 Job 并调度执行,执行过程中会创建两个调度器:DAGScheduler 和 TaskScheduler。
1、DAGScheduler 负责 Stage 级的调度,主要是将 job 切分成若干 Stages,并将每个 Stage 打包成 TaskSet 交给TaskScheduler 调度。
2、TaskScheduler 负责 Task 级的调度,将 DAGScheduler 给过来的 TaskSet 按照指定的调度策略分发到 Executor 上执行,调度过程中 SchedulerBackend 负责提供可用资源,其中 SchedulerBackend 有多种实现,分别对接不同的资源管理系统。
Driver 初始化 SparkContext 过程中