[半转]遇到Map-side Aggregation OOM 异常
原文来自:http://blog.csdn.net/macyang/article/details/9260777?
?
通读了一下,进行翻译:
在MapReduce job下面,有个Combiner,工作机制是将Reducer的工作分担一部分给Map阶段来做。
在Hive的执行计划优化中也是如此,默认情况下会开启Map-side Aggregation优化的功能。
?
select distinct id from tbl;
select id from tbl group by id;
这2种写法虽然可以得到相同的结果,但是执行计划则有很大的区别。
使用distinct效率更高一些,因为会使用到Map-side Aggregation,就是在map阶段进行去重,相对需要付出更多的内存空间。
第二种写法会把idshuffle到reduce上面进行去重,效率很低,但是稳定。
?
出现 error:?Out of memory due to hash maps used in map-side aggregation.异常的时候,
很大的可能是因为在做distinct的对象,重复率很低,导致map阶段里面维护的一个内存Map对象非常巨大。
如在word count example中。
会把单词每一个拆分出来,维护到一个key(单词)-value(数量)的内存Map里面,
然后再放到Reducer里面。
加入单词的重复数很低,那么这个内存Map超过了JVM配置的Map进程的内存大小的限制,就会出现上面的error了。
?
那么进行如下的配置修改是什么意思呢?
set hive.map.aggr.hash.percentmemory = 0.25
?
意思是说,当内存的Map大小,占到JVM配置的Map进程的25%的时候(默认是50%),就将这个数据flush到reducer去,以释放内存Map的空间。
?
其他的解决方法:
或者干脆关掉 MapAggregation?,不建议~~
set hive.map.aggr=false;
如果内存Map超过一定大小,就关闭MapAggregation功能
set hive.map.aggr.hash.min.reduction=0.5;
?
对于数据倾斜情况:
set hive.groupby.skewindata=true;
数据据倾斜的时候进行负载均衡,当选项设定为 true,生成的查询计划会有两个 MR Job。
第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;
第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。
?
?
?
?
?