4. Spark UI 深度解读:Jobs、Stages、Storage、Environment、Executors、SQL Tab 页面的关键指标
Spark UI 是诊断模型训练与推理任务性能问题的第一现场。每个 Tab 页面承载了不同维度的运行时快照,掌握关键指标的含义与异常模式,能帮助运维人员从“看到报错”升级为“在报错前发现风险”。本章按 Tab 逐一拆解核心指标与排查要点。
4.1 Jobs Tab:作业级进度与失败根因
Jobs 页面展示所有提交的 Spark 作业(Action 触发)。关键指标如下:
| 指标 | 含义 | 异常信号 |
|---|---|---|
| Job ID | 作业唯一编号,按提交顺序递增 | ID 跳跃过大可能表示中间有失败重试 |
| Description | 触发该作业的代码调用栈(如 count()、save()) | 出现大量相同 Description 可能表示死循环或重试风暴 |
| Submitted / Duration | 提交时间与总耗时 | Duration 远高于基线(如训练作业 > 2× 正常值) |
| Stages: Succeeded / Total | 成功 Stage 数与总 Stage 数 | Succeeded < Total 表示有 Stage 失败,需点开查看 |
| Tasks: Succeeded / Total | 成功 Task 数与总 Task 数 | 大量 Failed / Killed Task 说明资源或数据倾斜 |
排查要点: 当模型训练作业失败时,优先查看最后一个 Failed Job 的 Failed Stages 链接,而不是直接翻日志。UI 中会直接显示异常类名与错误栈的前几行,比原始日志更聚焦。
4.2 Stages Tab:Task 级瓶颈与数据倾斜
Stages 页面是性能分析的黄金入口。每个 Stage 对应一个 Shuffle 边界或计算阶段。
- Shuffle Read / Write:分别表示从上游读取和写入下游的数据量。若 Shuffle Read 远大于输入数据量,说明存在数据膨胀(如笛卡尔积或未优化的
groupByKey)。 - Input / Output:从存储系统读取和写入的数据量。模型训练中 Output 通常为 0(无显式写操作),若 Output 突增可能误写了中间结果。
- Task Time 分布:在 Stage 详情页的 Summary Metrics 表格中,关注
Duration列的Min、Median、Max。若 Max 是 Median 的 10 倍以上,强烈提示数据倾斜。 - Speculative Tasks:如果开启了推测执行,Killed Task 数量增多说明部分节点执行缓慢。
实战案例: 某模型训练 Stage 的 Task Duration 分布为 Min=2s, Median=5s, Max=180s。检查发现某个分区包含大量空值特征,导致计算路径异常。通过
repartition() 按特征哈希重新分区后,Max 降至 12s。
4.3 Storage Tab:RDD / DataFrame 缓存与内存压力
Storage 页面列出所有被 persist() 或 cache() 的 RDD 或 DataFrame。模型训练中常见缓存策略为 MEMORY_AND_DISK。
| 指标 | 含义 | 异常信号 |
|---|---|---|
| RDD Name | 缓存对象的名称(通常为代码变量名) | 出现大量未预期的缓存对象,可能忘记 unpersist() |
| Storage Level | 缓存级别(如 Memory Deserialized 1x Replicated) | 频繁出现 Disk 说明内存不足,数据被溢写到磁盘 |
| Cached Partitions | 已缓存的分区数 | 远小于总分区数表示缓存未完全生效 |
| Fraction Cached | 缓存数据占 Executor 内存的比例 | > 0.8 时极易触发 Full GC 或 OOM |
| Size in Memory / Size on Disk | 内存与磁盘中的缓存大小 | Disk 占比突增说明内存压力大,需增加 spark.memory.fraction |
注意: 模型训练中若使用
cache() 缓存训练集,请确保在 epoch 结束后调用 unpersist()。否则 Storage Tab 中会堆积大量过时缓存,导致 Executor 内存被无效数据占用,触发频繁 GC 甚至任务失败。
4.4 Environment Tab:配置冲突与版本不一致
Environment 页面以键值对形式展示 Spark 配置、JVM 参数、系统属性。排查配置问题时,此页面比 spark-defaults.conf 更可靠,因为它反映的是运行时实际生效的值。
- Spark Properties:重点关注
spark.executor.memory、spark.executor.cores、spark.sql.shuffle.partitions。若与预期不符,检查是否被代码中的spark.conf.set()覆盖。 - Classpath Entries:检查是否有多个版本的依赖包(如
jackson、hadoop-common)。版本冲突常表现为NoSuchMethodError或ClassNotFoundException。 - Runtime Information:查看 Java 版本与 Scala 版本。模型训练中若使用 GPU 调度,还需确认
spark.plugins是否包含 GPU 插件。
排查技巧: 当遇到
java.lang.NoSuchMethodError 时,先在 Environment Tab 的 Classpath 中搜索报错类所在的 JAR,对比集群中其他正常作业的版本。通常使用 mvn dependency:tree 在构建阶段解决,但 UI 能快速定位运行时差异。
4.5 Executors Tab:资源利用率与故障定位
Executors 页面是资源维度的核心面板。每个 Executor 一行,展示其 CPU、内存、磁盘、Shuffle 使用情况。
| 指标 | 含义 | 异常信号 |
|---|---|---|
| RDD Blocks | 该 Executor 上缓存的 Block 数 | 分布不均表示缓存倾斜 |
| Storage Memory | 已用 / 可用存储内存 | 已用接近可用时,新缓存会触发溢写或驱逐 |
| Shuffle Write | 该 Executor 写入的 Shuffle 数据量 | 某个 Executor 的 Shuffle Write 远高于其他,说明数据倾斜 |
| Shuffle Read | 该 Executor 读取的 Shuffle 数据量 | 同样可用于检测倾斜,配合 Stages 页面交叉验证 |
| Tasks | 已完成的 Task 数 / 最大并发 Task 数 | Task 数远小于其他 Executor 可能表示该节点故障或资源不足 |
| Failed / Killed | 失败与被杀死的 Task 数 | 单个 Executor 出现大量 Failed 说明该节点有问题 |
| GC Time | 垃圾回收总耗时 | GC Time 占比 > 10% 时,需调整内存或减少对象创建 |
快速定位故障节点: 在 Executors 页面按 Failed Tasks 降序排列。若某个 Executor 的 Failed 数远高于其他,且其 Address 列显示的主机名与其他不同,大概率是该主机硬件异常(磁盘坏道、内存故障)。建议立即将该节点从集群中移除。
4.6 SQL Tab:物理计划与执行瓶颈
SQL Tab 展示 DataFrame / SQL 查询的物理执行计划,以 DAG 可视化形式呈现。模型训练中,数据预处理阶段的 SQL 查询常在此页面暴露性能问题。
- Physical Plan 节点:每个节点代表一个物理操作(如
Scan、Filter、HashAggregate、ShuffleExchange)。点击节点可查看详细指标。 - Scan 节点:关注
number of output rows与size of output。若扫描了大量行但后续 Filter 过滤掉 99%,说明分区裁剪或谓词下推未生效。 - ShuffleExchange 节点:表示一次 Shuffle 操作。若出现多个 ShuffleExchange,说明查询计划未优化,可能缺少
repartition()或coalesce()。 - WholeStageCodegen:表示该阶段被编译为单段 Java 代码。若某个 Stage 未启用 Codegen,可能是查询过于复杂或包含非表达式函数。
优化案例: 某模型预处理 SQL 在 SQL Tab 中显示 3 次 ShuffleExchange。分析发现是因为先
groupBy 后 join 再 groupBy。通过将两个 groupBy 合并为一次窗口函数计算,Shuffle 降为 1 次,Stage 耗时减少 60%。
4.7 各 Tab 联动排查矩阵
实际排查中,单一 Tab 的信息往往不足以定位根因。下表总结了常见异常现象与需要联动的 Tab:
| 异常现象 | 优先查看 Tab | 联动 Tab | 典型根因 |
|---|---|---|---|
| 作业整体慢 | Jobs | Stages → Executors | 资源不足或数据倾斜 |
| 部分 Task 失败 | Stages | Executors → Environment | 节点故障或依赖版本冲突 |
| 频繁 GC / OOM | Executors | Storage → Environment | 缓存过多或内存配置不当 |
| Shuffle 耗时异常 | Stages | SQL → Executors | 分区数不合理或数据倾斜 |
| 配置未生效 | Environment | Jobs (确认作业 ID) | 代码中动态覆盖配置 |
最佳实践: 每次模型训练作业运行后,建议截图保存 Jobs 与 Executors 页面的关键指标。建立基线后,当 Duration 或 GC Time 偏离基线 20% 时自动告警,比等到作业失败再排查效率高得多。