我正在使用hadoop 2.4。 reducer使用几个大的内存映射文件(总共大约8G)。 reducer本身使用的内存非常少。据我所知,记忆映射文件(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 :(得分:1)
从日志中,您似乎已在yarn.nodemanager.pmem-check-enabled
中启用了yarn.nodemanager.vmem-check-enabled
和yarn-site.xml
属性。如果启用了这些检查,则NodeManger
可能会在容器检测到容器超出资源限制时终止容器。在您的情况下,物理内存超过配置值(= 4G),因此NodeManager
终止任务(在容器内运行)。
在正常情况下,堆内存(使用-Xmx
和mapreduce.reduce.java.opts
配置中的mapreduce.map.java.opts
属性定义)定义为总内存的75-80%(使用mapreduce.reduce.memory.mb
定义和mapreduce.map.memory.mb
配置)。但是,在您的情况下,由于Java内存映射文件的实现,非堆内存要求高于堆内存,这就是为什么您必须在总内存和堆内存之间保持相当大的差距。
答案 1 :(得分:0)
请检查以下链接,可能需要调整属性mapreduce.reduce.shuffle.input.buffer.percent