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

EMR on EKS:FSx Lustre+动态分配下空闲Executor无法终止排查

EMR on EKS 动态资源分配+持久化Shuffle存储问题排查

环境与现状

在EMR 7.8.0(Spark 3.5.4)on EKS环境中,采用FSx Lustre作为持久化存储,通过KubernetesLocalDiskShuffleDataIO插件实现Shuffle数据恢复,目标是在长尾任务阶段终止空闲Executor以优化成本。当前状态:

  • Executor扩容正常,FSx挂载无问题
  • Shuffle数据可正常持久化到FSx
  • 空闲(0活跃任务)的Executor虽设置60s空闲超时仍无法终止,持续占用资源
  • 未使用FSx时,动态资源分配(DRA)可部分生效,但多数持有Shuffle数据的Executor无法释放

待解答问题

  1. KubernetesLocalDiskShuffleDataIO插件是否因认为Shuffle数据仍需保留而阻止Executor终止?
  2. 超时设置是否过于保守,是否需调整得更激进?
  3. 是否存在EMR专属配置覆盖了动态分配行为?

同时想了解:有无成功在EMR on EKS上实现动态分配+持久化Shuffle存储的案例?我遗漏了哪些配置?

当前Spark配置

"spark.dynamicAllocation.enabled": "true",
"spark.dynamicAllocation.shuffleTracking.enabled": "true", 
"spark.dynamicAllocation.minExecutors": "1",
"spark.dynamicAllocation.maxExecutors": "200",
"spark.dynamicAllocation.initialExecutors": "3",
"spark.dynamicAllocation.executorIdleTimeout": "60s",
"spark.dynamicAllocation.cachedExecutorIdleTimeout": "90s",
"spark.local.dir": "/data/spark-tmp",
"spark.shuffle.sort.io.plugin.class": "org.apache.spark.shuffle.KubernetesLocalDiskShuffleDataIO",
"spark.kubernetes.executor.volumes.persistentVolumeClaim.spark-local-dir-1.options.claimName": "fsx-lustre-pvc",
"spark.kubernetes.executor.volumes.persistentVolumeClaim.spark-local-dir-1.mount.path": "/data",
"spark.kubernetes.executor.volumes.persistentVolumeClaim.spark-local-dir-1.mount.readOnly": "false",
"spark.kubernetes.driver.ownPersistentVolumeClaim": "true", 
"spark.kubernetes.driver.waitToReusePersistentVolumeClaim": "true",
"spark.shuffle.file.buffer.size": "1m", 
"spark.sql.adaptive.localShuffleReader.enabled": "false", 
"spark.eventLog.enabled": "true",
"spark.sql.adaptive.enabled": "true",
"spark.serializer": "org.apache.spark.serializer.KryoSerializer"

环境信息

  • EMR 7.8.0
  • Spark 3.5.4
  • Kubernetes 1.32
  • FSx Lustre

问题解答与配置补充

1. KubernetesLocalDiskShuffleDataIO 是否阻止Executor终止?

是的,这是核心原因。KubernetesLocalDiskShuffleDataIO将Shuffle数据存储在持久化FSx卷上,而Spark动态资源分配默认会保留持有未读取Shuffle数据的Executor——即使Executor处于空闲状态。

你开启的spark.dynamicAllocation.shuffleTracking.enabled=true仅针对本地磁盘Shuffle跟踪,对于外部存储插件持久化的Shuffle数据,Spark的跟踪机制无法自动感知数据是否已被读取完毕,因此会持续保留对应Executor。

2. 超时设置是否需要调整?

调整超时时间无法解决根本问题。即使把executorIdleTimeout设得更短,只要Executor关联的Shuffle数据被标记为"需保留",Spark就不会触发终止逻辑。超时设置仅对无Shuffle数据、无缓存数据的空闲Executor生效。

3. 是否存在EMR专属配置覆盖动态分配?

EMR on EKS确实有部分专属配置可能影响DRA行为,但从你提供的配置看未触发冲突。需额外检查以下参数:

  • spark.emr.dynamicAllocation.enabled:若设为false会覆盖原生Spark的DRA配置(默认与spark.dynamicAllocation.enabled联动为true)
  • spark.emr.executor.gracefulShutdownTimeout:设置过长可能延迟终止,但不会阻止终止

成功案例与遗漏配置

EMR on EKS实现动态分配+持久化Shuffle存储的核心是让Spark正确识别Shuffle数据生命周期,补充以下配置即可解决问题:

必须添加的配置

# 开启Shuffle数据清理机制,允许Spark删除不再使用的数据
"spark.shuffle.cleaner.enabled": "true",
# 配置Shuffle数据保留时长,超时自动清理(可根据任务时长调整,示例为300s)
"spark.shuffle.cleaner.interval": "300s",
# 开启Kubernetes环境下的Shuffle数据跟踪超时
"spark.dynamicAllocation.shuffleTracking.timeout": "300s",
# 允许Spark在Shuffle数据持久化到外部存储后释放对应Executor
"spark.shuffle.sort.io.plugin.kubernetes.localDiskShuffleDataIO.allowExecutorRelease": "true"

额外优化配置

  • spark.sql.adaptive.shuffle.targetPostShuffleInputSize:调整自适应Shuffle目标大小,减少Shuffle数据量,加速数据读取完成时间
  • spark.kubernetes.executor.deleteOnTermination:确保Executor终止时自动清理关联PVC资源(若使用动态PVC)

验证步骤

  1. 添加上述配置后提交任务,观察Executor状态
  2. 在Spark UI的Executors页面,检查空闲Executor的"Shuffle Data"列是否变为0
  3. 确认超过executorIdleTimeout后,无Shuffle数据的空闲Executor被自动终止

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 19:34:55