题目重点:用 stage/task 指标区分数据规模、倾斜、spill、GC 和文件碎片,再选择有证据的优化。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 把‘过大’先拆成执行慢、内存溢出、shuffle spill、多小文件或结果集过大等不同故障;不能先假定加机器。
- 训练分析以 Spark SQL/DataFrame 批作业为例,具体调优参数随版本和集群环境变化;题目未明确这些条件。
解题路线
- 先取 Spark UI 的 stage DAG、task 耗时分布、input/shuffle bytes、spill、GC、executor lost 和 query plan;比较同一 stage 的中位数与极慢任务以识别倾斜。
- 数据扫描过大先做列裁剪、过滤下推、分区裁剪和合理文件大小;若结果本身太大,确认是否误用 collect 或单分区输出。
- shuffle 过大时看宽依赖和聚合形态,提前过滤/预聚合,避免无谓 repartition;内存压力检查数据序列化、缓存策略和每 task 数据量,不能只调 executor memory。
- 发现热点 key 倾斜后量化最重分区,考虑拆热键、盐化或 AQE skew 优化,并比较前后计划。保留输出行数与聚合正确性校验,防止优化改语义。
- 上线以总时间、P95 task、shuffle/spill、资源成本和重跑稳定性对照;参数变更在固定数据快照上实验,避免数据量变化误导结论。
手动走一遍
一项 200 个 task 的 stage,199 个约 30 秒而 1 个跑 20 分钟:先查该 task 的输入行数和 key 分布,若独占热点 key,增大集群但不拆倾斜仍可能被一项尾部任务拖慢。数字只是诊断示例,非题目规模。
规模与取舍
扫描规模 N 的操作至少触及需要读取的数据;shuffle 网络/磁盘量与中间行数相关。不能在没有分区数、key 分布、硬件与 query plan 时给固定复杂度或资源配方。
易错点与追问
容易失分的边界
- 一见 job 慢就先加 executor,忽略单个倾斜 task。
- 把 collect 到 driver 当分布式结果处理。
- 频繁 repartition 增加 shuffle,却没有测分区大小。
- 盲目 cache 大表导致存储挤占执行内存。
- 仅看作业时间,不校验输出行数和业务指标。
继续深挖
- 如何区分数据倾斜与整体数据量增长?
- shuffle spill、GC 时间和 executor OOM 分别指向什么?
- AQE 有效时还需手工 salting 吗?
- 如何设数据快照与复现基准比较改动?
技术参考
- Apache Spark 官方 Tuning:序列化、内存和网络调优依据。
- Apache Spark 官方 RDD Shuffle 指南:shuffle 的网络、磁盘、spill 成本。
