我在运行类似wordcount的 mapreduce程序时遇到了奇怪的错误。我有一个带有20个从站的hadoop集群,每个都有4 GB RAM。我将我的map任务配置为具有300MB的堆,并且我的reduce任务槽获得1GB。我有2个映射插槽和每个节点1个减少插槽。一切顺利,直到第一轮地图任务完成。然后进展仍然是100%。我想那时正在进行复制阶段。每个地图任务都会生成如下内容:
Map output bytes 4,164,335,564
Map output materialized bytes 608,800,675
(我正在使用SnappyCodec进行压缩)
在停止大约一个小时后,reduce任务会出现以下异常:
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 common link
我不明白为什么hadoop在复制和合并时会遇到任何问题,如果它能够执行terasort基准测试。不能将所有地图输出都放入reducer线程的RAM中。那么这里发生了什么?
在上面提供的链接中,他们讨论了如何调整以下参数:
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仍然<1,所以关注我的第二个解决方案帖子!) 在重新开始这个密集模拟之前,我很高兴听到有人对我所面临的问题发表意见,因为它现在困扰了将近一周。我似乎也不完全理解在这个复制阶段发生了什么,我希望磁盘上的合并排序不需要太大的堆大小?
提前感谢提前获取任何有用的评论和答案!
答案 0 :(得分:14)
我认为线索是我的减少任务的堆积几乎完全需要用于减少阶段。但是 shuffle阶段正在竞争相同的堆空间,这种冲突导致我的工作崩溃。我认为这解释了为什么如果我降低shuffle.input.buffer.percent
,作业就不会崩溃。
答案 1 :(得分:7)
您引用mapred.job.shuffle.input.buffer.percent
的参数显然是预先Hadoop 2参数。我可以在1.04 docs的mapred-default.xml中找到该参数,但它的名称已根据2.2.0 docs更改为mapreduce.reduce.shuffle.input.buffer.percent
。
根据文档,此参数的描述为:
在随机播放期间从最大堆大小分配到存储映射输出的内存百分比。
要完全了解Sort和Shuffle,请参阅Chapter 6.4 of The Hadoop Definitive Guide。该书提供了参数mapred.job.shuffle.input.buffer.percent
的替代定义:
在随机播放的复制阶段,要分配给地图输出缓冲区的总堆大小的比例。
由于您发现将mapred.job.shuffle.input.buffer.percent
的默认值0.7
从0.2
降低到{{1}}可以解决您的问题,因此可以说您也可以通过增加reducer堆大小的值来解决您的问题。
答案 2 :(得分:0)
相关错误 - https://issues.apache.org/jira/browse/MAPREDUCE-6724
如果计算出的maxSingleShuffleLimit&gt;可能导致NegativeArraySizeException MAX_INT