社区首页 > Hadoop > 遇到Map-side Aggr...

遇到Map-side Aggregation OOM 异常

来自: 白开水

回复量:1

创建时间: 2017-03-06 09:56

通读了一下,进行翻译:

在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 中),最后完成最终的聚合操作。


0

1 回复

抹茶冰激凌 1F 2017-03-06 09:56:51

 点赞

回复 赞(
发表回复