如何清理Spark阶段间临时shuffle文件避免磁盘空间不足错误
Spark 3.2.0 (EMR 6.6) Shuffle临时文件阶段间隙清理配置方案
你对shuffle文件生命周期的判断是准确的:未开启shuffle复用、容错重算的场景下,单阶段生成的shuffle临时文件仅会被紧邻的下游阶段读取,后续阶段不会访问该部分数据,消费完成后删除不会影响作业正常运行。
Spark默认未按阶段边界自动清理shuffle文件的核心原因是,默认回收逻辑完全不感知作业阶段进度,仅靠两类机制触发清理:
- 定时GC扫描:默认每30分钟扫描一次过期shuffle文件,默认判定过期的留存时长达1小时,扫描周期长、判定阈值宽松
- 应用/Executor退出全量清理:仅在整个Spark作业执行完成、或Executor进程退出时,才会批量删除节点上归属该应用的所有shuffle临时文件
可直接生效的配置调整
在spark-submit提交参数中增加以下配置,即可实现shuffle文件在下游消费完成后立即清理,本地磁盘最多留存相邻两个阶段的shuffle数据,无需扩容EBS或替换计算引擎:
# 开启External Shuffle Service的shuffle主动删除能力(EMR 6.6默认开启节点级ESS,无需额外修改集群配置) spark.shuffle.service.removeShuffle=true # 缩短shuffle清理扫描周期,从默认30min调整为30s,确保引用失效后快速触发删除 spark.cleaner.periodicGC.interval=30s # 关闭清理操作对计算任务的阻塞,避免清理逻辑影响作业性能 spark.cleaner.referenceTracking.blockingFraction=0.0 # 开启分区级shuffle数据读后即删(Spark 3.2新增特性),单分区数据被下游task完全读取后立即触发回收,无需等整个阶段执行完成 spark.sql.adaptive.shuffle.partitionDataCleanup.enabled=true
注意事项
- 如果你的作业使用了
persist/cache缓存上游shuffle数据、或开启了阶段重跑容错能力,需要额外增加配置spark.cleaner.referenceTracking.cleanCheckpoints=true,避免缓存引用导致shuffle文件无法被正常识别为可回收状态 - 配置生效后可以登录EMR Core节点,进入默认shuffle临时目录
/mnt/yarn/usercache/[你的应用ID]/查看磁盘占用,正常情况下不会出现全链路所有阶段shuffle文件堆积的问题,磁盘占用峰值会随作业阶段数增加出现明显下降。
内容的提问来源于stack exchange,提问作者Mattreex
相关产品推荐
相关产品推荐

