我正在运行Hadoop作业,在我的yarn-site.xml文件中,我有以下配置:
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>2048</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>4096</value>
</property>
但是,我偶尔会遇到以下错误:
Container [pid=63375,containerID=container_1388158490598_0001_01_000003] is running beyond physical memory limits. Current usage: 2.0 GB of 2 GB physical memory used; 2.8 GB of 4.2 GB virtual memory used. Killing container.
我发现通过增加yarn.scheduler.minimum-allocation-mb,为容器分配的物理内存会增加 . 但是,我并不总是希望为我的容器分配4GB,并且认为通过明确指定最大大小,我可以解决这个问题 . 我意识到Hadoop无法弄清楚在映射器运行之前需要为容器分配多少内存,所以我应该如何在需要额外内存的情况下为容器分配更多内存?
2 回答
如果上述任何配置没有帮助 . 如果问题与映射器内存有关,我想建议需要检查的几件事情是 .
检查 combiner is enabled or not ?如果是,那么这意味着必须在所有记录(mapper的输出)上运行reduce逻辑 . This happens in memory. 根据您的应用程序,您需要检查启用组合器是否有帮助 . 权衡是在网络传输字节和时间/内存/ CPU之间为减少逻辑'X'记录的数量 .
如果你觉得合成器 Value 不大,那就禁用它 .
如果你需要组合器并且'X'是一个庞大的数字(比如数百万条记录),那么考虑改变你的分割逻辑(对于默认输入格式使用较少的块大小,通常1块大小= 1分割)将较少数量的记录映射到单个映射器 .
在单个映射器中处理的记录数 . 请记住,所有这些记录都需要排序 in memory (映射器的输出已排序) . 如果需要,请考虑将 mapreduce.task.io.sort.mb (默认值为200MB)设置为更高的值 . mapred-configs.xml
如果上述任何一个没有帮助,请尝试将映射器逻辑作为独立应用程序运行,并使用Profiler(如JProfiler)对应用程序进行概要分析,并查看内存的使用位置 . 这可以为您提供非常好的见解 .
您还应该正确配置MapReduce的内存分配 . 来自this HortonWorks tutorial:
最后,this thread in the Hadoop mailing list中有人遇到了同样的问题,在他们的情况下,事实证明他们的代码中存在内存泄漏 .