目录
问题描述
有三张表,A,B,C;其中c表有3百万条数据,a,b表没有数据,
第一次,空表在前,大表在后,(常规的优化方案)写法insert into table d select * from a left b on xxx=xxx inner join c on ixxx=xxx;
在spark-sql客户端执行,没有指定参数,相当于默认driver-memory=512M,executer-memory=512M;
结果执行一段时间后一直在报错,下面显示的进度条卡在最后一个task,然后提示Failed to allocate a page (16777216 byte)....
第二次yarn上执行 spark-sql --master yarn -f xxx.sql --num-executors 20 --executor-cores=2 --executor-memory=2g --driver-memory=1g;sql语句没有修改,执行报错和上面相同;
查资料均显示内存不足,并且看执行进度条卡顿明显,猜测可能是数据倾斜导致;
解决方法
1.改参数
2.修改sql
改参数: 先增大executor内存,因为测试环境是已知a,b表没有数据,但是生产上a、b表可能是小的,不建议修改sql
在再次将executor内存调大到6g问题依旧存在;
只能尝试修改sql,最终将大表c写在前面,空表在后面,sql轻松执行成功,在最原始的spark-sql 客户端未指定运行参须依然可以运行,屏幕显示的进度条也没有出现长时间卡顿的情况;具体原因位置;
后来百度出来有说加大driver内存和executor内存,减少executor-cores数量,
先是将executor内存改为4g,driver内存改为4g,其他不变,在yarn执行,结果成功,
为了看到具体是哪一个参数影响,再次尝试,只增大driver内存到4g其他参数不变,运行结果成功,
将driver内存改为2g其他不变(spark-sql --master yarn -f xxx.sql --num-executors 20 --executor-cores=2 --executor-memory=2g --driver-memory=2g;),执行结果成功; 并且执行进度中也没有出现明显的卡顿
总结
有效的解决方案
1,修改sql语句,将原来的空表在前大表在后调整为大表在前空表在后,问题解决,并且不需要修改任何参数
2.,增大driver内存问题解决,但是任然留有疑问。
疑问:为什么增大driver内存问题就解决了?。还有为什么空表在前执行失败,大表在前就成功,而正常优化是小表在前,会自动广播大各个节点,减少数据传输消耗,这里为什么不适用?大表在前和小表在前用explain查看执行计划除了位置不同外没有大发现不同的地方。
这里先记下,可能要先看一下源码。后期搞清楚了在补上