2. Spark作业基础架构回顾:Driver、Executor、Cluster Manager角色,作业提交流程,RDD/DAG/Stage/Task概念
在深入模型监控与异常排查之前,必须牢固掌握Spark的底层运行机制。本章将系统回顾Spark作业的四大核心支柱:角色定义、提交流程、核心抽象(RDD)以及调度层级(DAG/Stage/Task)。这些概念是后续诊断资源瓶颈、任务倾斜、内存溢出等异常的基础。
2.1 核心角色:Driver、Executor 与 Cluster Manager
Spark采用经典的Master-Slave(主从)架构,在集群中主要包含三个角色。理解它们的职责边界,是定位故障的第一步。
| 角色 | 进程位置 | 核心职责 | 异常排查关注点 |
|---|---|---|---|
| Driver | 集群中一台节点(或客户端) | 解析用户代码、构建DAG、调度Task、维护SparkContext | Driver OOM、UI无响应、任务提交失败 |
| Executor | 集群中多个Worker节点 | 执行Task、缓存RDD数据、向Driver汇报心跳与状态 | Executor丢失、Shuffle拉取失败、GC频繁 |
| Cluster Manager | 独立服务(如YARN RM) | 管理集群资源、分配Container、协调Driver与Executor的启动 | 资源不足、队列阻塞、AM超时 |
运维提示: 在模型训练场景中,Driver通常负责加载模型结构并下发广播变量(如模型权重),而Executor负责执行前向/反向传播。若Driver内存过小,极易在广播大模型时触发
java.lang.OutOfMemoryError。
2.2 作业提交流程:从提交到运行
一个Spark作业从提交到执行,经历以下关键步骤。掌握此流程有助于快速定位“作业卡住”或“提交失败”的根因。
- 提交脚本:用户通过
spark-submit命令启动作业,指定主类、JAR包、配置参数。 - 启动Driver:Cluster Manager在集群中分配一个Container(或本地进程)启动Driver,Driver初始化
SparkContext。 - 申请资源:Driver向Cluster Manager反向注册并申请Executor资源。
- 启动Executor:Cluster Manager在Worker节点上启动多个Executor进程,Executor向Driver注册并建立心跳连接。
- 分发任务:Driver将用户代码(如模型训练逻辑)转换为Task,分发到各Executor执行。
- 执行与反馈:Executor执行Task,将计算结果或中间数据写回Driver或存储系统,直至作业完成。
流程图:Spark作业提交流程(YARN Cluster模式)
2.3 核心抽象:RDD(弹性分布式数据集)
RDD是Spark最基本的数据抽象,代表一个不可变、可分区、可并行计算的数据集合。在模型监控中,训练数据、验证数据、模型预测结果通常都以RDD或DataFrame(基于RDD)的形式存在。
- 弹性:当某个分区数据丢失时,可通过血缘关系(Lineage)重新计算恢复。
- 分区:数据被切分为多个分区(Partition),每个分区对应一个Task。
- 只读:RDD本身不可变,只能通过
transformation操作生成新的RDD。 - 惰性求值:
transformation操作只记录转换逻辑,不立即计算;只有遇到action操作时才触发实际计算。
异常排查要点: 当模型训练数据量过大且分区数设置不合理时,容易导致单个Executor内存溢出。建议根据Executor核数设置合理的分区数(通常为2-3倍核数),并监控
spark.sql.shuffle.partitions参数。
2.4 调度层级:DAG → Stage → Task
Spark将用户代码转换为可执行任务的过程,分为三个层级。这是理解作业执行计划与性能瓶颈的核心。
| 层级 | 粒度 | 生成者 | 说明 |
|---|---|---|---|
| DAG(有向无环图) | 作业级 | DAGScheduler | 将RDD的血缘关系转换为DAG图,表示计算步骤的依赖关系 |
| Stage(阶段) | 阶段级 | DAGScheduler | 根据宽依赖(Shuffle)将DAG切分为多个Stage,Stage内部无Shuffle |
| Task(任务) | 分区级 | TaskScheduler | 每个Stage包含多个Task,每个Task处理一个分区数据,是实际执行单元 |
结构图:DAG → Stage → Task 调度层级
2.5 关键概念总结
| 概念 | 定义 | 与模型监控的关系 |
|---|---|---|
| Job | 一个Action操作触发一个Job | 模型训练中的每个epoch可能对应多个Job |
| Stage | Job按Shuffle切分的阶段 | Stage耗时过长通常意味着数据倾斜或Shuffle瓶颈 |
| Task | Stage内的最小执行单元 | Task失败或重试是Executor异常的直接信号 |
| Partition | RDD的数据分片 | 分区数影响并行度,过少导致资源闲置,过多导致调度开销 |
| Shuffle | 跨Stage的数据重分区 | Shuffle是性能杀手,也是磁盘/网络IO异常的常见来源 |
实战建议: 在Spark UI的“Stages”页面中,重点关注“Shuffle Read Size/Records”指标。若某个Stage的Shuffle Read量远大于其他Stage,极大概率存在数据倾斜,需考虑重新分区或调整聚合逻辑。