2014-09-25 137 views
0

我有简单的映射器和下面这个简单的减速机(它是由一个外地加盟的两个大表):Hadoop的内存使用:减少容器运行超出了物理内存限制

protected void reduce(StringLongCompositeKey key, Iterable<Text> values, Context context) 
      throws IOException, InterruptedException {} 
    foreach(Text text : values) { 
     // do some operations with one record and then emit it using context.write 
     // so nothing is storing in memory, one text record is small (mo more then 1000 chars) 
    } 
} 

,但我得到了以下错误

14/09/25 17点54分59秒INFO mapreduce.Job:地图100%减少28%

14/09/25 17点57分14秒INFO mapreduce.Job:任务标识:attempt_1410255753549_9772_r_000020_0,状态:失败

Container [pid = 24481,containerID = container_1410255753549_9772_01_001594]超出了物理内存限制。当前使用情况:使用4 GB物理内存4.1 GB;使用4.8 GB的8.4 GB虚拟内存。杀死容器。

有一个细微差别 - )

Iterable<Text> values 

很长!正如我之前所考虑的,并且仍然相信这是事实,Iterable会根据需求加载下一个记录,并且hadoop处理它不应该成为问题,而不会消耗大量的RAM。

在洗牌或排序时出现此错误吗?有没有关于处理长序列的特殊信息?

回答

1

在洗牌或排序时会出现此错误吗?

确实。在代码实际运行之前,当数据被移动到缩减器时,这似乎正发生在随机播放阶段。

减少百分比的工作方式是0-33%是洗牌阶段,数据发送给减速器,33-66%是排序阶段,最后33%代表容器运行。

0

似乎洗牌排序内存不足。你可以检查你的配置,看看你是如何分配内存的。通过使用java.opts,可以确保Reducer的java堆不会声明所有内存,因为它还需要OS和核心进程的内存。作为一个经验法则,我为这些留下了512MB。洗牌排序中的内存不足可能与洗牌排序竞争内存有关。降低允许洗牌使用的百分比通常可以解决问题。 Ofc,最好的设置取决于你的设置。

mapreduce.reduce.memory.mb=4096 
mapreduce.reduce.java.opts="-server 
-Xmx3584m -XX:NewRatio=8 -Djava.net.preferIPv4Stack=true" 
mapreduce.reduce.shuffle.input.buffer.percent=0.2