You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark作业处理~50-55GB数据集时OOM问题排查及内存疑问咨询

问题分析与解答

一、OOM错误的可能原因

  • 数据倾斜:总数据量55GB看似不大,但如果某个shuffle key对应的数据量远高于平均水平(比如某个key占了几十GB),单个任务处理该分区时会直接耗尽executor的执行内存。即使总executor内存足够,单任务内存过载依然会触发OOM。
  • Executor内存划分不合理:你给每个executor分配了22GB内存,但Spark默认会将executor内存划分为三部分:
    • 执行+存储内存:占总executor内存的60%(约13.2GB),由spark.memory.fraction控制
    • 其他内存:占20%(约4.4GB),用于JVM本身、依赖库等开销
    • 用户内存:占20%(约4.4GB),用于用户自定义数据结构等
      如果任务的执行内存需求超过13.2GB的限制,就会引发OOM。
  • Shuffle阶段内存压力叠加:每个executor并行运行4个任务,若这些任务同时处于shuffle阶段(比如shuffle write时生成临时文件、shuffle read时拉取并合并数据),多个任务的内存开销会累积,超过执行内存的阈值。即使单个任务的内存需求不高,并行任务的叠加也可能触发OOM。
  • Delta表读取的隐藏开销:Delta表的元数据处理、版本合并、小文件合并等操作可能导致实际处理的数据量远超标称的55GB;如果谓词下推失效,Spark会读取更多无关数据,增加内存压力。
  • JVM GC配置问题:若JVM垃圾回收策略不合理(比如默认的串行GC),内存无法及时释放,导致内存碎片或堆积,最终引发OOM。

二、分区内存占用的疑问解答

不需要将executor分配的13个分区一次性全部放入内存。Spark的任务调度逻辑是:

  • 每个executor的并行任务数等于核数(你的配置是4核,同时运行4个任务),同一时间仅会将这4个任务对应的分区数据加载到内存处理,其余待处理的分区会留在磁盘上等待调度。
  • 但需要注意两个例外场景:
    1. 若开启了数据缓存(cache()/persist()),处理完成的分区数据会被缓存到executor的存储内存中,若缓存的分区过多,会占用大量内存。
    2. 当shuffle内存不足时,Spark会将中间数据spill到磁盘(默认开启spark.shuffle.spill),但如果spill速度跟不上数据生成速度,依然会导致内存溢出。

内容的提问来源于stack exchange,提问作者user16798185

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 04:51:07