Spark OOM 内存溢出排查与调优实战

按 Driver 与 Executor 触发位置和 Shuffle、缓存、数据倾斜等场景分类,给出 Spark OOM 排查决策树与调优参数参考

袋鼠云
袋鼠云
高质量数据集 数据治理

Spark 作业 OOM(OutOfMemoryError)是大数据开发中最常见的故障之一。排查的关键是先确定 OOM 发生在 Driver 还是 Executor,再按具体场景定位根因。

Driver OOM:结果收集与广播溢出

Driver OOM 通常发生在两个阶段:collect/take 操作将 Executor 结果拉取到 Driver 内存,以及广播变量加载到 Driver。

典型症状:作业在 action 触发时(如 collect()、count()、show())报 Java heap space 或 GC overhead limit exceeded。

排查路径:第一步,检查是否使用了 collect()。如果结果集超过 Driver 内存(默认 1g),会直接 OOM。解决方案是用 take()、limit() 或写入文件替代 collect()。第二步,检查广播变量大小。spark.sql.autoBroadcastJoinThreshold 默认 10MB,如果广播表实际大小远超预期,需要调整阈值或改用 SortMergeJoin。第三步,检查 Driver 的 maxResultSize 配置。spark.driver.maxResultSize 默认 1g,如果单个任务结果超过此值会报错。

调优参数:spark.driver.memory 默认 1g,建议根据结果集大小调整为 2-4g;spark.driver.maxResultSize 根据最大结果集大小设置;spark.sql.autoBroadcastJoinThreshold 根据最大广播表大小调整。

离线开发 BatchWorks

支持多模态、覆盖集成开发调度运维的一站式离线数据开发平台

了解产品

Executor OOM:Shuffle、缓存与数据倾斜

Executor OOM 是更常见的场景,根因通常分为三类:Shuffle 写入溢出、缓存数据倾斜和数据膨胀。

场景一:Shuffle 写入溢出

典型症状:OOM 发生在 Shuffle Write 阶段,错误信息包含 SortShuffleWriter 或 ExternalSorter。

根因:Shuffle 过程中需要在内存中对数据进行排序和合并,当单个 Reduce Task 的数据量超过 executor 内存时会溢出到磁盘,但如果溢出目录空间不足或排序缓冲区过小,会触发 OOM。

调优方案:增大 spark.shuffle.sort.bypassMergeThreshold(默认 400),超过此值的分区会跳过排序直接合并;调整 spark.shuffle.spill.initialMemoryThreshold 控制溢出阈值;增加 executor 内存或减少 executor 数量。

场景二:数据倾斜

典型症状:大部分 Task 很快完成,但个别 Task 长时间运行后 OOM。通过 Spark UI 可以看到某些 Task 的 Shuffle Read 数据量远大于其他 Task。

根因:JOIN、GROUP BY 或 DISTINCT 操作中,某个 Key 的数据量远超其他 Key,导致单个 Reduce Task 处理的数据量过大。

调优方案:对倾斜 Key 添加随机前缀(salting),打散到多个 Reduce Task;使用 AQE(Adaptive Query Execution)的 Skew Join 优化(Spark 3.0+);对大表和小表使用 BroadcastJoin 替代 SortMergeJoin;检查数据源是否有异常值或默认值导致的 Key 倾斜。

场景三:缓存数据膨胀

典型症状:OOM 发生在 cache/persist 操作后,或者在迭代计算(如 ML 算法)中随迭代次数增加而 OOM。

根因:缓存的数据量超过可用内存,或者序列化方式(默认 Java 序列化)导致内存占用膨胀。

调优方案:使用 MEMORY_AND_DISK 存储级别,允许缓存数据溢出到磁盘;切换为 Kryo 序列化(spark.serializer=org.apache.spark.serializer.KryoSerializer);用 unpersist() 及时释放不再需要的缓存;检查是否存在未关闭的临时 DataFrame 导致内存泄漏。

数据治理

统一标准、质量、安全与资产管理,沉淀高质量数据集,支撑经营决策、监管合规与 AI 应用。

了解解决方案

通用排查清单

查看 Spark UI 的 Executors 标签页,确认内存使用峰值;检查 GC 日志,确认是否频繁 Full GC;检查数据量是否因上游数据膨胀而超出预期;确认 executor 内存配置是否匹配集群物理资源;对长周期作业检查是否存在迭代计算导致的状态积累。

OOM 排查的核心是"定位位置、识别场景、针对性调优"。大多数 OOM 都可以通过调整内存参数、优化数据分布或改变计算策略来解决,而不一定需要增加硬件资源。

开启Data+AI 之旅

填写表单,获取专属解决方案

400-002-1024

工作日 9:00-18:00

关注公众号

获取最新产品动态与技术干货

关注公众号

企业微信

扫码添加企业微信