容器超出内存限制
在Hadoop v1中,我已经分配了大小为1GB的每个7映射器和缩放器插槽,我的映射器和缩减器运行良好。 我的机器有8G内存,8个处理器。 现在用YARN,当在同一台机器上运行相同的应用程序时,我得到了容器错误。 默认情况下,我有这个设置:
<property> <name>yarn.scheduler.minimum-allocation-mb</name> <value>1024</value> </property> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>8192</value> </property> <property> <name>yarn.nodemanager.resource.memory-mb</name> <value>8192</value> </property>
它给了我错误:
Container [pid=28920,containerID=container_1389136889967_0001_01_000121] is running beyond virtual memory limits. Current usage: 1.2 GB of 1 GB physical memory used; 2.2 GB of 2.1 GB virtual memory used. Killing container.
然后我尝试在mapred-site.xml中设置内存限制:
<property> <name>mapreduce.map.memory.mb</name> <value>4096</value> </property> <property> <name>mapreduce.reduce.memory.mb</name> <value>4096</value> </property>
但仍然出现错误:
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.
我很困惑为什么地图任务需要这么多的内存。 在我的理解中,1GB的内存足够用于我的map / reduce任务。 为什么当我给容器分配更多的内存时,这个任务使用更多? 是因为每个任务都有更多的分裂吗? 我觉得一点点减小容器的大小,创build更多的容器是更高效的,这样就可以同时运行更多的任务。 问题是我怎样才能确保每个容器不会被分配更多的分裂比它可以处理?
您还应该正确configurationMapReduce的最大内存分配。 从这个HortonWorks教程 :
[…]
我们集群中的每台机器都有48 GB的RAM。 部分RAM应该保留用于操作系统使用。 在每个节点上,我们将为“YARN”分配40 GB RAM,并为操作系统保留8 GB
对于我们的示例集群,我们有一个Container的最小RAM(yarn.scheduler.minimum-allocation-mb)= 2 GB。 我们将为Map任务容器分配4 GB,为Reduce任务容器分配8 GB。
在mapred-site.xml中:
mapreduce.map.memory.mb
:4096
mapreduce.reduce.memory.mb
:8192每个Container将为Map和Reduce任务运行JVM。 JVM堆大小应设置为低于上面定义的Map和Reduce内存,以便它们位于由YARN分配的Container内存的范围内。
在mapred-site.xml中:
mapreduce.map.java.opts
:-Xmx3072m
mapreduce.reduce.java.opts
:-Xmx6144m
以上设置configuration了Map和Reduce任务将使用的物理RAM的上限 。
把它们加起来:
- 在YARN中,您应该使用
mapreduce
configuration,而不是mapred
的configuration。 编辑:这个评论是不适用了,现在你已经编辑你的问题。 - 你正在configuration的实际上是你想要多less,而不是分配的最大值是多less。
- 最大限制使用上面列出的
java.opts
设置进行configuration。
最后,你可能想要检查这个其他问题 ,描述一个类似的问题(和解决scheme)。
在纱线级别检查垂直和物理内存使用率。 问题不仅在于虚拟机没有足够的物理内存。 但是这是因为对于给定的物理内存,虚拟内存的使用量超过预期。
注意 :由于其大量的虚拟内存分配,这种情况发生在Centos / RHEL 6上。
它可以通过以下方式来解决:
-
通过将yarn.nodemanager.vmem-check-enabled设置为false来禁用虚拟内存使用情况检查。
-
通过将yarn.nodemanager.vmem-pmem-ratio设置为更高的值来增加VM:PM比率。
参考文献
https://issues.apache.org/jira/browse/HADOOP-11364
http://blog.cloudera.com/blog/2014/04/apache-hadoop-yarn-avoiding-6-time-consuming-gotchas/
在yarn-site.xml中添加以下属性
<property> <name>yarn.nodemanager.vmem-check-enabled</name> <value>false</value> <description>Whether virtual memory limits will be enforced for containers</description> </property> <property> <name>yarn.nodemanager.vmem-pmem-ratio</name> <value>4</value> <description>Ratio between virtual memory to physical memory when setting memory limits for containers</description> </property>
由于声誉低下,我无法对接受的答案发表评论。 不过,我想补充一句,这个行为是有devise的。 NodeManager正在查杀你的容器。 这听起来像你正在尝试使用hadoopstream,作为map-reduce任务的subprocess运行。 NodeManager监视任务的整个进程树,如果它分别占用比mapreduce.map.memory.mb或mapreduce.reduce.memory.mb中设置的最大内存大的内存,我们会期望Nodemanager终止任务,否则你的任务是窃取属于其他容器的内存,这是你不想要的。
EMR中使用HIVE的问题非常相似。 没有现存的解决scheme为我工作 – 即没有mapreduceconfiguration为我工作; 也没有把yarn.nodemanager.vmem-check-enabled
为false。
然而,最后的工作是设置tez.am.resource.memory.mb
,例如:
hive -hiveconf tez.am.resource.memory.mb=4096
另一个考虑调整的设置是yarn.app.mapreduce.am.resource.mb
当在EMR中使用spark时,我遇到了同样的问题,并且设置maximizeResourceAllocation=true
做了窍门; 希望它可以帮助别人。 您必须在创build群集时进行设置。 从EMR文档:
aws emr create-cluster --release-label emr-5.4.0 --applications Name=Spark \ --instance-type m3.xlarge --instance-count 2 --service-role EMR_DefaultRole --ec2-attributes InstanceProfile=EMR_EC2_DefaultRole --configurations https://s3.amazonaws.com/mybucket/myfolder/myConfig.json
哪里myConfig.json应该说:
[ { "Classification": "spark", "Properties": { "maximizeResourceAllocation": "true" } } ]