博客
关于我
从Container内存监控限制到CPU使用率限制方案
阅读量:384 次
发布时间:2019-03-05

本文共 4804 字,大约阅读时间需要 16 分钟。

前言

最近在运维我们部门的Hadoop集群时,发现了很多Job OOM的现象。频繁的Full GC导致了严重的性能问题。Full GC会导致“stop the world”,一旦Full GC的时间超过几分钟,其他活动都会受到影响。因此,必须找到原因并解决它。本文将介绍我们是如何解决这个问题,并在此基础上进行了一些优化。

Full GC源于何处

OOM的发生导致频繁的Full GC。首先需要确定具体原因。通常,第一个联想是上面的Job,Job的运行表现来自每个Task,而每个Task又表现为每个TaskAttempt。TaskAttempt运行在申请到的Container中。每个Container是一个独立的进程,可以通过jps命令在DataNode上看到大量名为“YarnChild”的进程,这些进程就是Container的启动进程。

初步估计是Container启动的JVM内存配置不足,导致内存不足。但问题并没有这么简单,这里还有些复杂。

为什么会发生Full GC

  • 内存配置不当:MapReduce任务的内存配置默认为1024MB(即1GB),但这可能不够,尤其是在处理大数据量或复杂任务时。错误的配置也可能导致JVM无法使用所需内存,从而引发OOM。

  • JVM配置错误:虽然mapreduce.map.memory.mbmapreduce.reduce.memory.mb是MapReduce任务的内存配置,但实际上它们并不是Container启动的JVM的内存配置。JVM的内存上限由mapreduce.map.java.optsmapreduce.reduce.java.opts决定。因此,理想的配置是java.opts的值必须大于等于memory.mb的值。如果配置不当,也会引发频繁的Full GC。

  • Container内存监控

    幸运的是,Hadoop已经对Container级别的内存进行了监控。对于所有启动的Container,Hadoop会额外启动一个名为container-monitor的线程,专门监控这些Container的物理内存和虚拟内存使用情况。相关的配置项包括:

    • yarn.nodemanager.pmem-check-enabled
    • yarn.nodemanager.vmem-check-enabled

    默认情况下,这两项都启用。内存监控的作用是一旦Container使用的内存超过JVM的最大内存上限,Container会被杀死。

    通过分析ContainersMonitorImpl.java可以看出,监控线程会在每隔一定时间(由YarnConfiguration.NM_CONTAINER_MON_INTERVAL_MS控制)遍历所有被监控的Container,检查它们的内存使用情况。如果内存使用超过限制,Container会被杀死。

    为什么只对Container内存做监控

    在解决上述问题后,我开始思考为什么不对CPU使用率也进行监控。同样重要的指标,CPU使用率为什么不一起监控呢?

    我总结了以下几点原因:

  • 影响更大:内存问题比CPU使用率问题影响更大,因为OOM会导致Full GC,一旦发生Full GC,整个应用都会受到影响。
  • 更常见:内存问题比CPU使用率问题更常见。大家在日常生活或编写程序时,更容易遇到内存不足的问题,而不是CPU不足的问题。
  • 密切相关:内存使用与Job处理的数据量密切相关。处理大数据量的Job,内存使用自然会更多,CPU使用率也会增加,但不会那么明显。
  • 综上所述,CPU监控并未被加入到监控代码中(个人分析)。但Hadoop自身并未加CPU监控并不代表我们不能添加这样的监控功能。例如,对于那些内存并不多,但会耗尽大量CPU资源的程序(如开很多线程但每个线程都做简单操作的程序),添加CPU使用率监控会有帮助。

    Container的Cpu使用率监控

    为了实现对CPU使用率的监控,我们需要:

  • 定义是否启用CPU使用率监控的配置:
  • /** Specifies whether cpu vcores check is enabled. */public static final String NM_VCORES_CHECK_ENABLED = NM_PREFIX + "vcores-check-enabled";public static final boolean DEFAULT_NM_VCORES_CHECK_ENABLED = false;

    默认情况下,CPU使用率监控是关闭的。同时,还需要定义一个使用阈值(0~1之间),一旦某个Container的CPU使用率超过这个阈值,Container就会被杀死。

    1. 定义CPU使用率的限制比例:
    2. /** Limit ratio of Virtual CPU Cores which can be allocated for containers. */public static final String NM_VCORES_LIMITED_RATIO = NM_PREFIX + "resource.cpu-vcores.limited.ratio";public static final float DEFAULT_NM_VCORES_LIMITED_RATIO = 0.8f;

      默认值为0.8,可以根据需要进行调整。

      1. serviceInit方法中进行配置初始化:
      2. private boolean pmemCheckEnabled;private boolean vmemCheckEnabled;private boolean vcoresCheckEnabled;private float vcoresLimitedRatio;...pmemCheckEnabled = conf.getBoolean(YarnConfiguration.NM_PMEM_CHECK_ENABLED, YarnConfiguration.DEFAULT_NM_PMEM_CHECK_ENABLED);vmemCheckEnabled = conf.getBoolean(YarnConfiguration.NM_VMEM_CHECK_ENABLED, YarnConfiguration.DEFAULT_NM_VMEM_CHECK_ENABLED);vcoresCheckEnabled = conf.getBoolean(YarnConfiguration.NM_VCORES_CHECK_ENABLED, YarnConfiguration.DEFAULT_NM_VCORES_CHECK_ENABLED);LOG.info("Physical memory check enabled: " + pmemCheckEnabled);LOG.info("Virtual memory check enabled: " + vmemCheckEnabled);LOG.info("Cpu vcores check enabled: " + vcoresCheckEnabled);if (vcoresCheckEnabled) {    vcoresLimitedRatio = conf.getFloat(YarnConfiguration.NM_VCORES_LIMITED_RATIO, YarnConfiguration.DEFAULT_NM_VCORES_LIMITED_RATIO);    LOG.info("Vcores limited ratio: " + vcoresLimitedRatio);}
        1. 在监控代码中使用计算出的CPU使用率进行判断:
        2. LOG.debug("Constructing ProcessTree for : PID = " + pId + " ContainerId = " + containerId);ResourceCalculatorProcessTree pTree = ptInfo.getProcessTree();pTree.updateProcessTree();long currentVmemUsage = pTree.getVirtualMemorySize();long currentPmemUsage = pTree.getRssMemorySize();// if machine has 6 cores and 3 are used, // cpuUsagePercentPerCore should be 300% and // cpuUsageTotalCoresPercentage should be 50%float cpuUsagePercentPerCore = pTree.getCpuUsagePercent();float cpuUsageTotalCoresPercentage = cpuUsagePercentPerCore / resourceCalculatorPlugin.getNumProcessors();
          1. 在核心逻辑中进行判断:
          2. } else if (isVcoresCheckEnabled() && cpuUsageTotalCoresPercentage > vcoresLimitedRatio) {    msg = String.format(        "Container [pid=%s,containerID=%s] is running beyond %s vcores limits."            + " Current usage: %s. Killing container.\n", pId,        containerId, vcoresLimitedRatio);    isCpuVcoresOverLimit = true;    containerExitStatus = ContainerExitStatus.KILLED_EXCEEDED_VCORES;}if (isMemoryOverLimit || isCpuVcoresOverLimit) {    // Virtual or physical memory over limit. Fail the container and    // remove the corresponding process tree    LOG.warn(msg);    // warn if not a leader    if (!pTree.checkPidPgrpidForMatch()) {        LOG.error("Killed container process with PID " + pId            + " but it is not a process group leader.");    }    // kill the container    eventDispatcher.getEventHandler().handle(        new ContainerKillEvent(containerId, containerExitStatus, msg));    it.remove();    LOG.info("Removed ProcessTree with root " + pId);} else {

            相关链接

    转载地址:http://gvng.baihongyu.com/

    你可能感兴趣的文章
    No module named ‘MySQLdb‘错误解决No module named ‘MySQLdb‘错误解决
    查看>>
    No new migrations found. Your system is up-to-date.
    查看>>
    No qualifying bean of type XXX found for dependency XXX.
    查看>>
    No qualifying bean of type ‘com.netflix.discovery.AbstractDiscoveryClientOptionalArgs<?>‘ available
    查看>>
    No resource identifier found for attribute 'srcCompat' in package的解决办法
    查看>>
    no session found for current thread
    查看>>
    No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
    查看>>
    NO.23 ZenTaoPHP目录结构
    查看>>
    no1
    查看>>
    NO32 网络层次及OSI7层模型--TCP三次握手四次断开--子网划分
    查看>>
    NOAA(美国海洋和大气管理局)气象数据获取与POI点数据获取
    查看>>
    NoClassDefFoundError: org/springframework/boot/context/properties/ConfigurationBeanFactoryMetadata
    查看>>
    node exporter完整版
    查看>>
    Node JS: < 一> 初识Node JS
    查看>>
    Node Sass does not yet support your current environment: Windows 64-bit with Unsupported runtime(72)
    查看>>
    Node 裁切图片的方法
    查看>>
    Node+Express连接mysql实现增删改查
    查看>>
    node, nvm, npm,pnpm,以前简单的前端环境为什么越来越复杂
    查看>>
    Node-RED中Button按钮组件和TextInput文字输入组件的使用
    查看>>
    Node-RED中Switch开关和Dropdown选择组件的使用
    查看>>