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

Spark提交至YuniKorn时如何实现资源动态分配?

Spark on YuniKorn 资源动态分配实践

Spark 配合 YuniKorn 完全可以实现资源动态分配——运行时按需扩容executor,任务完成后自动释放闲置executor。针对你遇到的「查询完成后executor未被移除」问题,结合实践经验从配置和环境层面逐一排查:

1. 补全Spark动态分配的核心依赖配置

你的配置遗漏了动态分配生效的关键前提:必须启用外部shuffle服务,否则Spark会因担心丢失executor上的shuffle数据,拒绝回收闲置executor。需要添加:

conf.set('spark.shuffle.service.enabled', True)

注意:该服务需在集群节点提前部署(YARN环境需每个节点启动shuffle服务,K8s环境需配置shuffle服务Sidecar)。

2. 理解minExecutors的约束

你设置了spark.dynamicAllocation.minExecutors=2,这意味着Spark会始终保留至少2个executor,仅会回收超出此数量的闲置实例。如果你的作业运行时未扩容到超过2个executor,自然不会有executor被移除。

  • 若希望任务完成后尽可能释放资源,可将minExecutors设为0,但需注意初始executors配置的配合,避免后续任务启动的冷启动延迟。

3. 检查YuniKorn侧的资源回收开关

YuniKorn自身配置会直接影响资源回收逻辑:

  • 确认yunikorn-site.xml中application.resource.reclaim.enabled设为true,允许调度器主动回收应用闲置资源。
  • 检查作业所在队列的minResource配置,若队列设置了最小资源配额,YuniKorn会确保应用占用资源不低于该值,导致executor无法被回收。
  • 避免开启YuniKorn的gang scheduling( gang调度会为作业预留固定资源,阻止动态缩容)。

4. 处理Jupyter环境的特殊情况

Jupyter中Spark会话长期驻留,即使单个查询完成,Spark仍会默认预留资源应对后续任务,需手动触发回收:

  • 清除缓存数据:执行spark.catalog.clearCache(),若executor上存储了缓存的RDD/DataFrame,Spark会无限期保留该executor(除非设置了spark.dynamicAllocation.cachedExecutorIdleTimeout)。
  • 取消后台残留任务:执行spark.sparkContext.cancelAllJobs(),避免未完成的后台任务阻止executor被标记为闲置。

5. 补充优化配置

针对闲置executor回收,可添加以下配置优化效果:

# 缓存executor的闲置超时(默认无限期,有缓存时不会回收)
conf.set('spark.dynamicAllocation.cachedExecutorIdleTimeout', '60s')
# 调整资源申请的等待阈值,避免频繁扩容缩容
conf.set('spark.dynamicAllocation.schedulerBacklogTimeout', '5s')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 12:30:58