Glue作业遇MetadataFetchFailedException:调整repartition/worker数为何生效?
关于Glue作业
MetadataFetchFailedException异常的原因分析(移除repartition/减少worker数解决OOM的逻辑) 问题背景
处理约500MB数据的Glue作业,涉及两个100万行DataFrame的多外连接操作,结果行数未膨胀(≤100万行),但运行时抛出org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle异常(关联OOM),且基准测试显示单executor输入/Shuffle数据均小于100MB(远小于G2.X机型内存)。通过移除repartition步骤或将worker数从10调为3解决了问题,以下是具体原因:
一、移除repartition解决问题的核心原因
repartition操作会强制触发全量shuffle,虽然最终生成的shuffle数据量不大,但shuffle过程中的临时内存开销远超预估的静态数据量:
- shuffle阶段的临时内存占用:repartition执行时,executor需要在内存中完成数据的分区排序、序列化写入前的缓存。外连接后的DataFrame每行字段更多、结构更复杂,序列化后的临时数据体积会比原数据大,加上Spark shuffle buffer的预留内存,可能瞬间占满executor的可用堆内存,触发OOM。
- 小分区的内存开销累加:如果repartition设置的分区数远大于原DataFrame的分区数,会生成大量小分区。每个分区除了数据本身,还要占用额外的内存存储分区元数据、序列化缓存等,这些小开销累加后,会快速消耗executor内存,导致OOM。
- OOM引发的连锁故障:executor因OOM崩溃后,无法正常生成shuffle输出文件的元数据和数据块,后续其他executor尝试拉取shuffle数据时找不到对应位置,就会抛出
Missing an output location for shuffle异常。
二、减少worker数解决问题的核心原因
Glue的机型总内存是固定的,worker数量和单个worker的内存配额成反比:
- 单worker内存配额提升:比如G2.2Xlarge机型总内存16G,10个worker时每个worker能分配到的可用堆内存仅约1.5G(需扣除系统、Glue服务本身的内存占用),而减少到3个worker后,单worker可用内存能提升到5G左右。虽然单executor处理的shuffle数据不到100MB,但Spark运行时还有其他内存开销:广播变量、中间数据缓存、JVM堆内存碎片、BlockManager等组件的内存占用,这些开销累加后,低内存配额的worker容易触发OOM。
- 调度与资源竞争减少:worker数过多会增加集群调度的开销,executor之间可能出现磁盘IO、内存资源的争抢,间接导致shuffle阶段的内存压力陡增,引发OOM和后续的shuffle元数据异常。
内容的提问来源于stack exchange,提问作者Ajayv
相关产品推荐
相关产品推荐

