在生产环境中,spark 部署方式一般都是 yarn-cluster 模式,本文针对该模式进行讲解,当然大体思路也适用于其他模式

 

基础概念

一个 spark 应用包含 job、stage、task 三个概念

job:以 action 方法为界,一个 action 触发一个 job

stage:它是 job 的子集,以 RDD 宽依赖为界,遇到宽依赖即划分 stage

task:它是 stage 的子集,以分区数来衡量,分区数多少,task 就有多少

 

 

任务调度

spark 任务从发起到执行可用下图表示

Client-ResourceManage

1. Client 端通过 spark-submit + 参数 发起任务,即向 ResourceManage 提交 application,注意该 application 包含了一堆参数,如 Executor 数,Executor 内存,Driver 内存等;

2. ResourceManage 需要先判断现在资源是否能满足该 application,如果满足,则响应该 application,如果不满足,报错;

3. 如果资源满足,Client 端准备 ApplicationMaster 的启动上下文,并交给 ResourceManage;

4. 并且循环监控 application 的状态;

ResourceManage-ApplicationMaster

1. ResourceManage 找一个 worker 启动 ApplicationMaster;

2. ApplicationMaster 向 ResourceManage 申请 Container;

3. ResourceManage 收集可用资源,并告诉 ApplicationMaster;

4. ApplicationMaster 尝试在对应的 Container 上启动 Executor 进程;

ApplicationMaster-Driver

1. 有了资源,ApplicationMaster 启动 Driver;

  // Driver 线程主要是初始化 SparkContext 对象,准备运行所需上下文,并保持与 ApplicationMaster 的 RPC 连接,通过 ApplicationMaster 申请资源

2. Driver 启动成功后,告诉 ApplicationMaster;

Driver-Executor

1. Executor 启动成功后,反向注册到 Driver 上,并持续向 Driver 发送心跳;

2. Driver 启动 task,分发给 Executor,并监控 task 状态;

3. 当 Executor 任务执行完毕后,将任务状态发送给 Driver;

 

spark 的核心就是资源申请和任务调度,主要通过 ApplicationMaster、Driver、Executor 来完成

 

spark 任务调度分为两层,一层是 stage 级的调度,一层是 task 级的调度

 

RDD 间的血缘关系,代表了计算的流程,构成了 有向无环图,即 DAG;

最后通过 action 触发 job 并调度执行;

DAGScheduler 负责 stage 级的调度,主要是将 DAG 切分成多个 stage,并将 stage 打包成 TaskSet 交给 TaskScheduler;

TaskScheduler 负责 task 级的调度,将 DAGScheduler 发过来的 TaskSet 按照指定的调度策略发送给 Executor;

SchedulerBackend 负责给 调度策略 提供可用资源,调度策略决定把 task 发送给哪个 Executor;  【其中 SchedulerBackend 有多种实现,分别对接不同的资源管理系统】

 

基于上述认知,再来看一张图

Driver 在启动过程中,除了初始化 SparkContext 外,也初始化了 DAGScheduler、TaskScheduler、 SchedulerBackend 3个调度对象,同时初始化了 HeartbeatReceiver 心跳接收器;

并且各个线程之间保存通信;

SchedulerBackend 向 ApplicationMaster 申请资源,并不间断地从 TaskScheduler 获取 task 并发送给 合适的 Executor;

HeartbeatReceiver 负责接收 Executor 心跳报文,监控 Executor 存活状态;

 

 

 

参考资料:

https://www.cnblogs.com/LXL616/p/11165826.html