1. 基本概念
1.1 Application、Job、Stage、Task 的含义和关联
名称 | 含义 |
---|---|
Application | 用户提交的 Spark 应用程序 |
Job | Spark 作业,Application 的子集,由 action 算子触发 |
Stage | Job 的子集,以 RDD 的宽窄依赖为界 |
Task | Stage 的子集,Spark 中最基本的任务执行单元,每个 Task 执行的结果就是生成了目标 RDD 的一个 partiton |
1.2 任务调度中的关键角色
- 总结
- Driver 是运行用户程序 main() 函数并创建 SparkContext 的实例,是任务调度中最为关键的部分。
- Executor 是执行实际计算任务的实例,是任务调度的终点。
- SparkContext.createTaskScheduler 方法会初始化 TaskScheduler、SchedulerBackend。此外初始化 SparkContext 的过程中也会初始化 DAGScheduler。
- Driver 中的3大核心模块
模块 | 职责 |
---|---|
DAGScheduler | DAG 调度器,负责 Stage 的切分并生成 TaskSet 发送给 TaskScheduler |
TaskScheduler | Task 调度器,负责 Task 的管理(包括 Task 的提交和销毁) |
SchedulerBackend | 调度后端,维持和 Executor 的通信,并负责将 Task 提交到 Executor |
- Executor 中的3大核心模块
模块 | 职责 |
---|---|
ThreadPool | 任务执行的线程池,执行 Driver 端提交过来的 Task |
BlockManager | 存储管理器,为 RDD 提供缓存服务 |
ExecutorBackend | Executor 调度后端,维持与 Driver 端的通信,并将任务执行结果反馈给 Driver |
1.3 RPC 模块
Spark 的 RPC 模块主要负责 Spark 集群中各节点间的通信功能的实现。 RPC 框架的核心概念如下:
- RpcEnv(上下文环境);
- RpcEndpoint(响应 RpcEndpointRef 的 send 和 ask 请求,进行消息处理的通信终端);
- RpcEndpointRef(通过 ask 或者 send 向 RpcEndpoint 消息)。
2. 调度流程
2.1 源码方法调用链梳理
2.2 Stage 调度流程
(待补充)
- submit job
- create stage
- submit stage
- submit task
2.3 Task 调度流程
(待补充)
- 创建 TaskSetManager
- 生成 TaskDescription 发送给 Executor
- Executor 执行 task
3. Spark 推测执行机制
当 spark.speculation 设置为 true 时,就会对 task 开启推测执行,也就是在一个 stage 下跑的慢的 tasks 有机会重新启动。对于一个 stage 里面拖后腿的 task,会在其他节点的executor 上再次启动这个 task,如果其中一个 task 实例运行成功则将这个最先完成的 task的计算结果作为最终结果,同时会干掉其他 executor上运行的实例。
4. Spark 本地化调度机制
本地化调度即将计算任务移动到数据所在的节点,是大数据计算中提升性能的一种手段。Spark 中的本地化调度机制,就是“移动计算”的实现方案。
支持比如进程本地化(PROCESS_LOCAL,数据和Task在同一个 Executor 中,性能最好)、节点本地化(NODE_LOCAL,数据在进程间进行传输)、机架本地化(RACK_LOCAL,数据在节点间进行传输)…
如果当前本地化调度级别发布任务失败,则降低级别,尝试将期望级别较低的 Executor 资源提供给 Task,直至成功。