【问题标题】:Container is running beyond memory limits容器运行超出内存限制
【发布时间】:2014-01-08 20:18:01
【问题描述】:

在 Hadoop v1 中,我为每个 7 个映射器和减速器分配了 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.

我很困惑为什么 map 任务需要这么多内存。据我了解,1GB 的内存足以完成我的 map/reduce 任务。为什么当我为容器分配更多内存时,任务使用更多?是因为每个任务都有更多的拆分吗?我觉得稍微减小容器的大小并创建更多的容器会更有效,这样更多的任务可以并行运行。问题是我怎样才能确保每个容器不会被分配比它可以处理的更多的拆分?

【问题讨论】:

标签: hadoop mapreduce hadoop-yarn mrv2


【解决方案1】:

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

[...]

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

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

在mapred-site.xml中:

mapreduce.map.memory.mb: 4096

mapreduce.reduce.memory.mb: 8192

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

在mapred-site.xml中:

mapreduce.map.java.opts:-Xmx3072m

mapreduce.reduce.java.opts:-Xmx6144m

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

总结一下:

  1. 在 YARN 中,您应该使用 mapreduce 配置,而不是 mapred 配置。 编辑:由于您已编辑问题,此评论不再适用。
  2. 您所配置的实际上是您想要请求的数量,而不是要分配的最大值。
  3. 使用上面列出的java.opts 设置配置最大限制。

最后,您可能需要查看描述类似问题(和解决方案)的其他SO question

【讨论】:

  • 是的。通过设置mapreduce.map.java.optsmapreduce.reduce.java.opts 解决我的问题。您知道分配给任务的实际内存是否仅由mapreduce.map/reduce.memory.mb 定义? yarn.scheduler.minimum-allocation-mb 如何影响实际的内存分配?
  • @lishu,如果有帮助,请接受答案。关于你的最后一个问题,yarn 设置适用于集群中的任何容器分配;这包括 map 和 reduce 任务,但也包括来自其他类型应用程序的其他任务。 mapreduce 设置仅适用于 mapreduce 作业。
  • @cabad,我开发了一个 Lishu 正在使用的库。我想知道您是否会更改答案中的任何内容,因为知道 MR 任务正在产生一个实际上分配大部分内存的进程(hadoop 流)。当然 Xmx 设置不会影响外部进程,因为它不是 java 程序。感谢您的帮助。
  • Hortonworks 现在有一个名为 hdp-configuration-utils 的便捷工具来获取推荐值。从github.com/hortonworks/hdp-configuration-utils获取它
  • 如果应用正确的内存配置并不能解决问题(就像在我的情况下,实际上它在 ubuntu 上运行但在 CentOS 上运行的 hadoop 上工作)尝试禁用 vmem 检查:blog.cloudera.com/blog/2014/04/…
【解决方案2】:

在 Yarn 级别检查了虚拟和物理内存使用率。 问题不仅在于虚拟机没有足够的物理内存。但这是因为给定物理内存的虚拟内存使用量超出预期。

注意:由于 Centos/RHEL 6 会主动分配虚拟内存,因此会发生这种情况。

可以通过以下方式解决:

  1. 通过设置禁用虚拟内存使用检查 yarn.nodemanager.vmem-check-enabledfalse

  2. 通过将 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>

【讨论】:

  • 也感谢 CentOS 的提示 :-)
  • 在集群中的所有节点上将 yarn.nodemanager.vmem-check-enabled 设置为 false 并重新启动 Hadoop 服务修复了此问题
【解决方案3】:

我在 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

【讨论】:

  • 嗯@hiroprotagonist,您知道是否必须在 YARN 启动之前“调整”纱线参数,还是仅在应用时使用(并且可以从一项工作更改为下一项工作)?
  • 我已经能够在申请时进行设置。具体来说,在 hive 交互式控制台中。
【解决方案4】:

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

【讨论】:

    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

        • 在 WSL 上,错误消息包含荒谬的数字(至少对我而言):“...正在运行超出虚拟内存限制。当前使用情况:已使用 338.8 MB 的 2 GB 物理内存;481.1 GB使用了 4.2 GB 虚拟内存。正在杀死容器。”
        • @SamikR 是的,我也有类似的情况,我想这不是 hadoop 问题,而是 WSL 问题。也许我需要将演示转移到真正的 Linux 操作系统计算机上
        【解决方案8】:

        我正在练习 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>
        

        【讨论】:

          【解决方案9】:

          我没有亲自检查过,但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 来禁用虚拟内存检查。

          【讨论】:

            猜你喜欢
            • 2017-09-12
            • 2018-11-01
            • 2018-03-30
            • 1970-01-01
            • 1970-01-01
            • 2018-10-13
            • 2022-12-15
            • 1970-01-01
            • 2016-03-19
            相关资源
            最近更新 更多