Spark执行Insert语句查询多个大宽表Join时,SMJ算子出现内存不足导致coredump问题的解决方法
问题现象描述
Spark执行Insert语句且只有1个数据分区的场景,当出现50个表连续Sort Merge Join时,算子加速SMJ算子在堆外内存耗尽时调用new申请vector内存导致coredump问题。
关键过程、根本原因分析
由于算子加速当前是列式处理,相比于原生Spark的行式处理,内存占用会更大,而且SMJ算子计算过程中申请的资源需要在task结束后才能释放。
出现问题的场景是Insert语句且只有1个数据分区,Spark只会生成1个task去执行任务。因此,会导致50个表的Sort Merge Join都在1个task内执行。此时用例配置的38g堆外内存在连续50个SMJ算子计算过程中已经耗尽,此时再通过new申请内存时,出现coredump。
结论、解决方案及效果
该用例属于比较极限的场景,Spark作业本身是为了利用大规模集群的并发优势,正常情况下不会存在单个task(单线程)执行大量表Join的业务场景;当触发该问题时,可通过如下方法进行规避:
- 调整spark.memory.offHeap.size参数增大堆外内存后重新触发业务。
- 回退到原生Spark流程触发业务。
父主题: 故障排除