我正在使用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内存。这看起来很愚蠢。
也许减速机输入数据拷贝到内存中,而处理它,这些数据在作业停止前不会被丢弃,或者GC在清理时不是很快? – Ashalynd 2015-04-04 22:22:42
我使用java Runtime类来打印出maxMemory,totalMemory和freeMemory。最大不到2G,免费约1.2G。减速器使用的实际内存仅约为512M。所以我认为这不是垃圾收集。 – york 2015-04-05 02:14:00
映射的java内存由OS管理。它应该被多个进程重用(reducers?)我只是想知道如何使节点管理器与这些内存映射文件进行交互? – york 2015-04-05 02:19:13