Spark减少RDD分区数量后未降低进程内存与Executor核数问题咨询
Spark执行repartition/coalesce后未释放集群资源的原因分析
以下是该场景下资源未释放的核心原因:
- 缓存数据的Executor默认不会被动态回收
Spark动态资源分配默认会永久保留存储了RDD缓存数据的Executor,对应参数spark.dynamicAllocation.cachedExecutorIdleTimeout的默认值为Int.MaxValue(无限大)。你将40个分区的RDD全部缓存到内存后,这部分缓存数据分散在对应持有分区的Executor上,只要缓存没有被主动清理,这些Executor永远不会被动态回收,因此占用的vcores和内存不会释放。 - repartition/coalesce不会修改已缓存RDD的分区分布
这两个算子仅会改变后续生成的RDD的分区逻辑,不会合并或清理已经完成缓存的原始RDD的40个分区数据。后续处理逻辑改为10个并行度,只是指10个task会拉取原有40个缓存分区的数据进行计算,原有缓存分区所在的Executor仍然持有数据,不会被释放。 - 动态资源分配的Executor回收有触发条件限制
即使没有缓存数据,Executor也需要满足连续空闲时间超过spark.dynamicAllocation.executorIdleTimeout(默认60秒)才会被回收,同时回收后的Executor数量不能低于spark.dynamicAllocation.minExecutors设置的最小值。如果你的任务配置了较高的最小Executor数,或是后续还有间歇性的小任务在运行,也会导致Executor一直被占用。 - YARN队列资源统计逻辑是按持有Container计数
Cloudera CDP中YARN队列的vcores、内存配额占用是按应用当前持有的所有Executor Container计算的,只要Container没有被销毁归还给YARN,不管Executor上有没有运行task,都会被计入已占用资源,因此你看不到资源占用下降。
如果你需要主动释放多余资源,可以先调用rdd.unpersist()主动清理不再需要的RDD缓存,同时根据业务场景合理配置spark.dynamicAllocation.cachedExecutorIdleTimeout的超时时间,避免缓存Executor永久占用资源。
内容的提问来源于stack exchange,提问作者rajnish
相关产品推荐
相关产品推荐

