概要描述
本文主要介绍执行 inceptor sql 报错Topo check failed. Mapred tasks exceed 1000000000
的排查思路和解决办法。
详细说明
客户在对表执行group by
查询时,报错Topo check failed. Mapred tasks exceed 1000000000
,DBAService页面并未生成对应的task数目相关信息。
排查思路
- 查看建表语句,该表是一个范围分区orc事务表,分区字段
sk_period
,每个分区1999个分桶 - 执行
analyze
分析,可以看到存在21个分区下有1999个分桶。这和全表count查询的21*1999=41979 个task数目一致 - 通常来说,
group by
聚合查询DAG会生成2个stage,一个是map stage一个reduce stage,map task数量为41979,reduce task数量,一般是由map task数量和hive.groupby.aggregateratio
参数决定的,该参数默认是0.6,也就是说reduce task数目为41979 * 0.6 = 25187.4
解决方法
这里我们科普一下ngmr.topo.mapred.limit
这个参数,该参数表示 任意两个Stage之间Map数量和Reduce数量乘积,如果大于这个值则会报错,默认值:1000000000, 在上述排查思路中我们可以看到,map数量和reduce数量乘积为 41979*(41979 * 0.6)=1057341864.6
这个值是大于1000000000的,所以会触发报错。
注意! 不建议全局调大
ngmr.topo.mapred.limit
,这个参数如果超过了默认阈值,Inceptor Server会有比较严重的内存问题。
解决方案如下几种:
a) 方案一:(优先推荐该方案)计算端map合并
如果源表是textfile/orc非事务这些表类型,可以采用小文件合并参数,对map阶段task数目较多的表进行小文件合并降低map数量;
set inceptor.automerge.maptask = true;
set ngmr.partition.mergesize.mb = 100;
如果是orc事务表,考虑是否可以减少分桶数,或者使用更加合理的分区方式减少分区数;
如果是holodesk表,可以开启合并参数 SET holodesk.automerge.enabled=true;
(结合其他合并参数一起使用),或者尝试手动compact (alter table table_name compact 'full' and wait;
,再到DBAService检查下holodesk小文件的数量是否减少);
b) 方案二:(仅限于group by场景)降低hive.groupby.aggregateratio
, 该参数适用于group by
,可以降低Reduce Task 和 Map Task 的比例;
c) 方案三:(需要设置合理的reduce数目,不是很推荐)设定mapred.reduce.tasks
,直接强制干预reduce数目。