Mapreduce shuffle阶段的内存不足错误

DDW*_*DDW 16 hadoop mapreduce

我在运行类似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
Run Code Online (Sandbox Code Playgroud)

(我使用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
Run Code Online (Sandbox Code Playgroud)

我在Google上搜索并发现了这个链接,但我真的不知道该怎么做: hadoop常用链接

我不明白为什么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
Run Code Online (Sandbox Code Playgroud)

他们声称参数的乘积> 1的事实允许堆积错误.编辑:请注意,5*1.25*0.7仍然<1,所以关注我的第二个解决方案帖子!)在重新开始这个密集模拟之前,我会很高兴听到有人对我所面临的问题的看法,因为它几乎困扰着一周了.我似乎也不完全理解在这个复制阶段发生了什么,我希望磁盘上的合并排序不需要很多堆大小?

非常感谢您提供任何有用的评论和答案!

DDW*_*DDW 15

我认为线索是我的减少任务的堆积几乎完全需要用于减少阶段.但是洗牌阶段正在争夺相同的堆空间,这种冲突导致我的工作崩溃.我认为这可以解释为什么如果我降低工作量,工作就不会再崩溃了shuffle.input.buffer.percent.


har*_*are 8

您引用的参数mapred.job.shuffle.input.buffer.percent显然是预先Hadoop 2参数.我可以在1.04文档的mapred-default.xml中找到该参数,但它的名称已mapreduce.reduce.shuffle.input.buffer.percent根据2.2.0文档更改为.

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

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

有关Sort和Shuffle的完整理解,请参阅Hadoop权威指南的第6.4章.该书提供了参数的替代定义mapred.job.shuffle.input.buffer.percent:

在shuffle的复制阶段期间,要分配给映射的总堆大小的比例输出缓冲区.

既然你发现减少mapred.job.shuffle.input.buffer.percent它的默认值0.70.2解决你的问题,可以很自然地说你也可以通过增加reducer堆大小的值来解决你的问题.