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作业从提交到执行,经历以下关键步骤。掌握此流程有助于快速定位“作业卡住”或“提交失败”的根因。

  1. 提交脚本:用户通过 spark-submit 命令启动作业,指定主类、JAR包、配置参数。
  2. 启动Driver:Cluster Manager在集群中分配一个Container(或本地进程)启动Driver,Driver初始化SparkContext。
  3. 申请资源:Driver向Cluster Manager反向注册并申请Executor资源。
  4. 启动Executor:Cluster Manager在Worker节点上启动多个Executor进程,Executor向Driver注册并建立心跳连接。
  5. 分发任务:Driver将用户代码(如模型训练逻辑)转换为Task,分发到各Executor执行。
  6. 执行与反馈:Executor执行Task,将计算结果或中间数据写回Driver或存储系统,直至作业完成。
流程图:Spark作业提交流程(YARN Cluster模式)
Spark作业提交流程 spark-submit Cluster Manager (YARN ResourceManager) Worker Node (启动Executor) Driver SparkContext (DAG Scheduler / TaskScheduler) Executor (执行Task / 缓存数据) 流程说明 ① 提交作业 ② 启动Driver ③ 申请资源 ④ 启动Executor ⑤ 注册心跳 ⑥ 分发Task ⑦ 执行计算 ⑧ 返回结果 常见异常点: - Driver OOM - Executor丢失 - 资源申请超时 - Shuffle拉取失败

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 调度层级
DAG-Stage-Task调度层级 DAG(有向无环图) Stage 0(无Shuffle) 宽依赖边界 → Stage 1(Shuffle) Task 0 Task 1 Task 2 Task N 每个Task处理一个RDD分区,由Executor中的一个线程执行 Stage数量 = 宽依赖次数 + 1;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,极大概率存在数据倾斜,需考虑重新分区或调整聚合逻辑。