容器超出了内存限制

时间:2014-01-08 20:18:02

标签: hadoop mapreduce yarn mrv2

在Hadoop v1中,我已经分配了每个7GB的映射器和缩小器插槽,大小为1GB,我的映射器和放大器。减速机运行正常。我的机器有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任务。为什么当我为容器分配更多内存时,任务使用更多?是因为每个任务都有更多的分裂吗?我觉得稍微减小容器的大小并创建更多容器会更有效,这样就可以并行运行更多任务。问题是如何确保每个容器不会被分配比它可以处理的更多分裂?

9 个答案:

答案 0 :(得分:86)

您还应该正确配置MapReduce的最大内存分配。来自this HortonWorks tutorial

  

[...]

     

我们群集中的每台计算机都有48 GB的RAM。应该为操作系统使用保留一些RAM。在每个节点上,我们将为&gt; YARN分配40 GB RAM,并为操作系统保留8 GB

     

对于我们的示例群集,我们拥有Container的最小RAM   (yarn.scheduler.minimum-allocation-mb)= 2 GB。因此我们将分配4 GB   对于Map任务容器,以及8 GB用于Reduce任务容器。

     

在mapred-site.xml中:

     

mapreduce.map.memory.mb:4096

     

mapreduce.reduce.memory.mb:8192

     

每个Container都将为Map和Reduce任务运行JVM。 JVM   堆大小应设置为低于Map和Reduce内存   在上面定义,以便它们在Container的范围内   由YARN分配的内存。

     

在mapred-site.xml中:

     

mapreduce.map.java.opts-Xmx3072m

     

mapreduce.reduce.java.opts-Xmx6144m

     

以上设置配置物理RAM的上限   Map和Reduce任务将使用

总结一下:

  1. 在YARN中,您应该使用mapreduce配置,而不是mapred配置。 编辑:此评论现在已不再适用,因为您已编辑了问题。
  2. 您正在配置的实际上是您要请求的数量,而不是要分配的最大值。
  3. 使用上面列出的java.opts设置配置最大限制。
  4. 最后,您可能需要查看描述类似问题(和解决方案)的其他SO question

答案 1 :(得分:40)

对于垂直和物理内存使用率,在纱线级别进行检查。 问题不仅是VM没有足够的物理内存。但这是因为虚拟内存使用量超过预期的给定物理内存。

注意:由于其积极分配虚拟内存,因此在Centos / RHEL 6上发生这种情况。

可以通过以下方式解决:

  1. 通过设置禁用虚拟内存使用情况检查 yarn.nodemanager.vmem-check-enabled 改为 false ;

  2. 通过将 yarn.nodemanager.vmem-pmem-ratio 设置为更高的值来增加VM:PM比率。

  3. 参考

    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>
    

答案 2 :(得分:11)

我在EMR中使用HIVE时遇到了类似的问题。现有的解决方案都不适合我 - 也就是说,mapreduce配置都不适用于我;并且都没有将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

答案 3 :(得分:8)

由于声誉低,我无法对接受的答案发表评论。但是,我想补充一下,这种行为是设计的。 NodeManager正在杀死你的容器。听起来你正在尝试使用hadoop流,它作为map-reduce任务的子进程运行。 NodeManager监视任务的整个进程树,如果它分别占用的内存大于mapreduce.map.memory.mb或mapreduce.reduce.memory.mb中设置的最大内存,我们会期望Nodemanager终止任务,否则你的任务是窃取属于你不想要的其他容器的记忆。

答案 4 :(得分:1)

在EMR中使用spark时我遇到了同样的问题,设置maximizeResourceAllocation=true就行了;希望它可以帮到某人。您必须在创建群集时进行设置。来自EMR docs:

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"
    }
  }
]

答案 5 :(得分:1)

我们最近也遇到过这个问题。如果问题与映射器内存有关,我想建议需要检查的几件事情是。

  • 检查合并器是否已启用?如果是,那么这意味着必须在所有记录(mapper的输出)上运行reduce逻辑。 这种情况发生在内存中。根据您的应用程序,您需要检查启用组合器是否有帮助。权衡是在网络传输字节和在“X”记录数上减少逻辑的时间/内存/ CPU之间的权衡。
    • 如果你认为合成器价值不大,那就禁用它。
    • 如果你需要组合器并且'X'是一个庞大的数字(比如数百万条记录),那么考虑改变你的分割逻辑(对于默认输入格式使用较少的块大小,通常1块大小= 1分割)来映射较少的数量记录到单个映射器。
  • 在单个映射器中处理的记录数。请记住,所有这些记录都需要在内存中排序 (映射器的输出已排序)。如果需要,请考虑将 mapreduce.task.io.sort.mb (默认值为200MB)设置为更高的值。 mapred-configs.xml
  • 如果上述任何一项没有帮助,请尝试将映射器逻辑作为独立应用程序运行,并使用Profiler(如JProfiler)对应用程序进行概要分析,并查看内存的使用位置。这可以为您提供非常好的见解。

答案 6 :(得分:1)

在具有Ubunto OS的Windows Linux子系统上运行yarn,错误“超出虚拟内存限制,正在杀死容器” 我通过在文件yarn-site.xml中禁用虚拟内存检查来解决了该问题

<property> <name>yarn.nodemanager.vmem-check-enabled</name> <value>false</value> </property> 

答案 7 :(得分:0)

我没有亲自检查,但是hadoop-yarn-container-virtual-memory-understanding-and-solving-container-is-running-beyond-virtual-memory-limits-errors听起来很合理

我通过将yarn.nodemanager.vmem-pmem-ratio更改为更高的值来解决了这个问题,我同意:

另一个不建议使用的解决方案是通过将yarn.nodemanager.vmem-check-enabled设置为false来禁用虚拟内存检查。

答案 8 :(得分:0)

我正在练习 Hadoop 程序(版本 hadoop3)。通过虚拟机,我已经安装了 Linux 操作系统。我们在安装 Linux 时分配的内存非常有限。 通过在 mapred-site.xml 中设置以下内存限制属性并重新启动 HDFS 和 YARN,我的程序就可以运行了。

 <property>
    <name>mapreduce.map.memory.mb</name>
    <value>4096</value>
  </property>
  <property>
    <name>mapreduce.reduce.memory.mb</name>
    <value>4096</value>
  </property>