2015-04-04 79 views
2

我正在使用hadoop 2.4。减速器使用几个大型内存映射文件(总共大约8G)。减速机本身使用很少的记忆。据我所知,memeory映射文件(FileChannel.map(readonly))也使用少量内存(由OS而不是JVM管理)。当使用大内存映射文件时纱线容器内存不足

我得到这个错误:

Container [pid=26783,containerID=container_1389136889967_0009_01_000002] 
is running beyond physical memory limits. 
Current usage: 4.2 GB of 4 GB physical memory used; 
5.2 GB of 8.4 GB virtual memory used. Killing container 

这里是我的设置:

mapreduce.reduce.java.opts=-Xmx2048m 

mapreduce.reduce.memory.mb=4096 

所以我调整了参数,这和作品:

mapreduce.reduce.java.opts=-Xmx10240m 

mapreduce.reduce.memory.mb=12288 

我进一步调整参数并像这样工作:

mapreduce.reduce.java.opts=-Xmx2048m 

mapreduce.reduce.memory.mb=10240 

我的问题是:为什么我需要容器的容量比JVM的容量大8G?罪魁祸首似乎是我使用的大型Java内存映射文件(每个约1.5G,总计约8G)。不是由OS管理的内存映射文件,它们应该可以通过多个进程共享(例如reducer)?

我使用AWS m2.4xlarge实例(67G内存),它有大约8G未使用,操作系统应该有足够的内存。在当前设置中,每个实例只有大约5个可用的缩减器,每个还原器都有额外的8G内存。这看起来很愚蠢。

+0

也许减速机输入数据拷贝到内存中,而处理它,这些数据在作业停止前不会被丢弃,或者GC在清理时不是很快? – Ashalynd 2015-04-04 22:22:42

+0

我使用java Runtime类来打印出maxMemory,totalMemory和freeMemory。最大不到2G,免费约1.2G。减速器使用的实际内存仅约为512M。所以我认为这不是垃圾收集。 – york 2015-04-05 02:14:00

+0

映射的java内存由OS管理。它应该被多个进程重用(reducers?)我只是想知道如何使节点管理器与这些内存映射文件进行交互? – york 2015-04-05 02:19:13

回答

1

从日志中看来,您已启用yarn-site.xml中的yarn.nodemanager.pmem-check-enabledyarn.nodemanager.vmem-check-enabled属性。如果启用这些检查,则NodeManger可能会终止容器,如果它检测到容器超出资源限制。在你的情况下,物理内存超过配置的值(= 4G),因此NodeManager杀死了任务(在容器内运行)。

在正常情况下,堆存储器(使用mapreduce.reduce.java.optsmapreduce.map.java.opts配置-Xmx属性定义的)所限定的总存储器(使用mapreduce.reduce.memory.mbmapreduce.map.memory.mb配置所定义的)的75-80%。但是,在你的情况下,由于Java内存映射文件的实现,非堆内存需求比堆内存要高,这就是为什么你必须在总内存和堆内存之间保持相当大的差距。

0

请检查下面的链接,有可能需要调整财产mapreduce.reduce.shuffle.input.buffer.percent

Out of memory error in Mapreduce shuffle phase

+0

链接只有答案是不鼓励的。\t 请引用参考链接中答案的基本部分,因为如果链接的页面发生变化,答案可能会失效。 – 2015-10-13 16:07:06