Hadoop Mapreduce洗牌阶段内存不足错误

Hadoop Mapreduce洗牌阶段内存不足错误,hadoop,mapreduce,Hadoop,Mapreduce,运行类似于mapreduce的字数计算程序时,我遇到了奇怪的错误。我有一个hadoop集群,它有20个从机,每个从机都有4GB的RAM。我将映射任务配置为拥有300MB的堆,而reduce任务插槽获得1GB。每个节点有2个映射插槽和1个reduce插槽。在第一轮地图任务完成之前,一切都进展顺利。然后进展保持在100%。我想接下来的复制阶段就要开始了。每个映射任务生成如下内容: Map output bytes 4,164,335,564 Map output materialized by

运行类似于mapreduce的字数计算程序时,我遇到了奇怪的错误。我有一个hadoop集群,它有20个从机,每个从机都有4GB的RAM。我将映射任务配置为拥有300MB的堆,而reduce任务插槽获得1GB。每个节点有2个映射插槽和1个reduce插槽。在第一轮地图任务完成之前,一切都进展顺利。然后进展保持在100%。我想接下来的复制阶段就要开始了。每个映射任务生成如下内容:

Map output bytes    4,164,335,564
Map output materialized bytes   608,800,675
(我正在使用SnappyCodec进行压缩)

暂停约一小时后,reduce tasks会崩溃,但以下情况除外:

    Error: java.lang.OutOfMemoryError: Java heap space at  
org.apache.hadoop.mapred.ReduceTask$ReduceCopier$MapOutputCopier.shuffleInMemory(ReduceTask.java:1703) at
org.apache.hadoop.mapred.ReduceTask$ReduceCopier$MapOutputCopier.getMapOutput(ReduceTask.java:1563) at
org.apache.hadoop.mapred.ReduceTask$ReduceCopier$MapOutputCopier.copyOutput(ReduceTask.java:1401) at
org.apache.hadoop.mapred.ReduceTask$ReduceCopier$MapOutputCopier.run(ReduceTask.java:1333
我在谷歌上搜索并找到了这个链接,但我真的不知道该怎么做:

我不明白,如果hadoop能够执行terasort基准测试,为什么它在复制和合并时会遇到任何问题。不可能所有map输出都适合减速器螺纹的闸板。这是怎么回事

在上面提供的链接中,他们讨论了如何调整以下参数:

mapreduce.reduce.shuffle.input.buffer.percent = 0.7
mapreduce.reduce.shuffle.memory.limit.percent = 0.25
mapreduce.reduce.shuffle.parallelcopies = 5
他们声称,参数的乘积大于1这一事实允许出现重设错误。
编辑:注意5*1.25*0.7仍然是我认为线索是我的reduce任务的heapsize在reduce阶段几乎完全需要。但洗牌阶段正在争夺同一堆空间,由此产生的冲突导致我的工作崩溃。我想这就解释了为什么如果我降低
shuffle.input.buffer.percent

您引用的参数
mapred.job.shuffle.input.buffer.percent
显然是Hadoop 2之前的参数,那么作业就不会崩溃。根据,我可以在mapred-default.xml中找到该参数,但其名称已更改为
mapreduce.reduce.shuffle.input.buffer.percent

根据文档,此参数的描述为:

洗牌期间从最大堆大小分配到存储映射输出的内存百分比

有关排序和洗牌的完整理解,请参阅。该书提供了参数
mapred.job.shuffle.input.buffer.percent
的另一种定义:

在随机播放的复制阶段,要分配给映射输出缓冲区的总堆大小的比例


由于您观察到将
mapred.job.shuffle.input.buffer.percent的值从默认值
0.7
降低到
0.2
解决了您的问题,可以很安全地说,您也可以通过增加reducer的堆大小值来解决您的问题。

即使将
shuffle.input.buffer.percent
更改为0.2,它也不适用于我,并得到相同的错误

在单节点集群上进行了hit-and-trial之后,我发现
/
目录中需要有足够的空间,因为在溢出的情况下,进程会使用该空间

泄漏目录也需要更改。

相关错误-


如果在最新版本的hadoop中计算的maxSingleShuffleLimit>MAX_INT

参数已重命名为
mapred.reduce.parallel.copies
mapred.job.shuffle.input.buffer.percent
,则可能会导致NegativeArraySizeException,带有
shuffle.memory.limit
我找不到的参数。更新:设置
mapred.job.shuffle.input.buffer.percent=20
实际上解决了这个问题。但问题仍然悬而未决,它为什么能解决这个问题?这仅仅是hadoop中的一个bug吗?你是说set mapred.job.shuffle.input.buffer.percent=0.2对吗?我也有同样的问题。请告诉我在哪里可以降低shuffle.input.buffer.percent
,因为我不知道它的位置。这些参数都应该添加到mapred.site.xml中,但是一年前我在使用hadoop 1.2.1,请记住!在启动hadoop作业时,还可以使用-D参数进行设置。例如,hadoop jar MyJarFile.jar-Dmapreduce.reduce.shuffle.input.buffer.percent=0.2/input/dir/output/dir还想把它放在这里,因为它是相关的:我想我是在谈论hadoop 1.2.1,它已经很久以前了,但我会更新投票,因为答案更符合最新情况。谢谢(注意,在我的模拟中,reducer堆大小已经达到最大值,因此我必须找到一个不同的参数进行修改)谢谢!:-)我的回答更多的是提供问题的信息(太长了,无法评论)。您的解决方案完全有效。您所说的
在/directory
中需要足够的空间是什么意思?您的意思是说数据节点的根目录上应该有空间吗?Hadoop使用根(/)下的哪个特定目录?