EMR上Spark2.4.0处理1TB数据报FetchFailedException故障咨询
Spark作业Shuffle拉取失败故障排查
根因定位
- 参数拼写错误导致资源配置不生效:提交参数中
--exeuctor-cores 4存在拼写错误,正确应为--executor-cores 4,该错误会使配置不生效,Executor默认使用1核,处理性能不足大幅提升Shuffle拉取超时概率。 - 内存严重超配导致Executor被YARN主动Kill:单节点物理内存仅122G,你配置的单Executor内存总和达到
80G(Executor堆内存) + 50G(堆外内存) + 2G(YARN内存 Overhead) = 132G,远超过节点物理内存上限,YARN会直接杀掉超内存的Executor进程,导致其存储的Shuffle数据丢失,对应三类异常均为Executor进程异常退出后的表现:MetadataFetchFailedException:对应Executor退出后,Shuffle元数据丢失Executor is not registered:对应Driver尝试和已被Kill的Executor通信连接失败:对应Executor退出后端口无进程监听,网络连接被拒绝
- 高版本专属参数无效导致Shuffle数据丢失:你使用的Spark 2.4.0版本不支持
spark.dynamicAllocation.shuffleTracking.enabled参数,该参数为Spark 3.0.0新增特性,配置后完全不生效,动态分配回收空闲Executor时会直接删除其存储的Shuffle数据,下游Stage拉取时直接报错。 - Shuffle分区数不足加剧内存压力:1TB数据仅配置200个Shuffle分区,单分区数据量约5G,远高于Spark推荐的单分区128M-256M阈值,单Task处理压力过大进一步提升Executor OOM被Kill的概率。
修复方案
- 修正参数拼写,调整内存配置避免超配:
将--executor-memory调整为40G,spark.memory.offHeap.size调整为20G,spark.yarn.executor.memoryOverhead调整为8G,单Executor总内存控制在68G以内,单台16核节点可同时运行2个Executor,充分利用节点资源的同时无内存超配风险。 - 移除无效参数,优化动态分配配置:
删除spark.dynamicAllocation.shuffleTracking.enabled配置,显式配置spark.dynamicAllocation.maxExecutors为200,避免Executor申请过多导致节点资源耗尽。如果业务场景允许,可直接关闭动态分配,固定Executor数量为150,彻底避免Executor回收导致的Shuffle数据丢失问题。 - 调整Shuffle参数降低运行压力:
将spark.sql.shuffle.partitions调整为40008000,把单分区数据量降到128M256M区间,降低单Task处理压力。如果仍偶现Shuffle拉取失败,可新增配置spark.shuffle.io.maxRetries=10、spark.shuffle.io.retryWait=5s,提升Shuffle拉取重试次数,降低偶发网络波动的影响。
内容的提问来源于stack exchange,提问作者Shiloh Raj
相关产品推荐
相关产品推荐

