拆分Spark任务后Executor出现OOM(Yarn退出码143)问题咨询
拆分场景确实会改变Spark的内存使用逻辑,甚至可能加剧内存压力,最终引发Executor内存溢出和Yarn退出码143的问题,具体原因如下:
中间数据的存储与解析开销变化
原流程里,关联生成的Dataset是Spark内存中的逻辑执行产物,用的是Tungsten这类高效二进制编码格式,而且可能经过Catalyst优化自动做了列裁剪、数据压缩,内存占用非常紧凑。拆分后把中间Dataset写入Hive表,不管用Parquet还是ORC格式,写入时都会做序列化,读取时又要反序列化回内存——这个过程中如果没特意做列裁剪,中间表会保留全量字段,读取后内存里加载的数据量、格式冗余度都会比原流程直接传递的Dataset高很多。全局执行计划优化失效
原流程是端到端的单DAG作业,Spark Catalyst能做全局优化,比如把业务逻辑里的过滤、投影操作下推到关联阶段,提前减少内存里留存的数据量。拆分后变成两个独立作业,第二个作业只能基于中间表做局部优化,没法复用原有的全局优化逻辑,导致内存里要处理的数据量变大。而且原流程中Shuffle后的中间数据可能被自动缓存复用,拆分后第二个作业得从HDFS重新加载数据,没有缓存加持,内存压力自然更大。Yarn退出码143的本质原因
退出码143对应SIGTERM信号,说白了就是Executor内存超了被NodeManager强制杀掉。哪怕你增大了Executor内存,拆分后第二个作业的内存占用增长可能远超预期——比如原流程中间数据内存占10G,拆分后读取中间表可能占20G,单纯加内存未必能覆盖这种差异。额外潜在风险
比如中间表分区不合理,导致第二个作业读取时出现数据倾斜,某几个Executor扛了远超平均的数据量,直接爆内存;或者写入中间表时没开压缩,读取的原始数据量比原流程大好几倍,内存直接顶不住。
内容的提问来源于stack exchange,提问作者KUMAR K

