Hadoop-2.6.0 CPU CGroup实现分析

  1. 云栖社区>
  2. 博客>
  3. 正文

Hadoop-2.6.0 CPU CGroup实现分析

柏辰爸爸 2016-11-28 10:58:00 浏览1061
展开阅读全文

一、概述

       Hadoop-2.6.0中对CPU CGroups的实现,主要是通过CgroupsLCEResourcesHandler来实现的,通过它的int*()系列方法初始化一些参数和环境,比如CGroups的路径等,然后在启动容器内的可执行文

件前由LinuxContainerExecutor调用preExecute()方法,进行setupLimits()即设置限额操作,而在容器内的可执行退出后(无论成功还是失败)由LinuxContainerExecutor调用postExecute()方法,进行

clearLimits()即清除限额操作。

二、实现细节

      1、CgroupsLCEResourcesHandler配置

                   通过参数yarn.nodemanager.linux-container-executor.resources-handler.class配置

                   配置为org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler即可

                   参数默认值是org.apache.hadoop.yarn.server.nodemanager.util.DefaultLCEResourcesHandler。

      2、setupLimits()核心实现

                  参见如下代码注释:

/*
 * Next three functions operate on all the resources we are enforcing.
 */
 
private void setupLimits(ContainerId containerId,
                         Resource containerResource) throws IOException {
  String containerName = containerId.toString();
 
  if (isCpuWeightEnabled()) {
     
    // 取container申请到资源中的VCores,注意用的是虚拟core
    int containerVCores = containerResource.getVirtualCores();
     
    // 创建CGroup,其实就是在CGroup路径中创建与CPU和容器名称相关的路径
    createCgroup(CONTROLLER_CPU, containerName);
 
    // 对应隔离方式(一),即shares
    int cpuShares = CPU_DEFAULT_WEIGHT * containerVCores;
     
    // 更新CGroup,其实就是在上述路径中将数值cpuShares写入shares文件
    // 这个cpuShares的值就是container申请到资源中的VCores * 1024
    updateCgroup(CONTROLLER_CPU, containerName, "shares",
        String.valueOf(cpuShares));
     
    // 对应隔离方式(二),即cfs_period_us、cfs_quota_us
    // 这个是需要参数yarn.nodemanager.linux-container-executor.cgroups.strict-resource-usage设置为true的
    if (strictResourceUsageMode) {
      int nodeVCores =
          conf.getInt(YarnConfiguration.NM_VCORES,
            YarnConfiguration.DEFAULT_NM_VCORES);
      if (nodeVCores != containerVCores) {
        float containerCPU =
            (containerVCores * yarnProcessors) / (float) nodeVCores;
        int[] limits = getOverallLimits(containerCPU);
         
        // 更新CGroup,其实就是在上述路径中将数值limits[0]和limits[1]分别写入cfs_period_us文件和cfs_quota_us文件
        updateCgroup(CONTROLLER_CPU, containerName, CPU_PERIOD_US,
          String.valueOf(limits[0]));
        updateCgroup(CONTROLLER_CPU, containerName, CPU_QUOTA_US,
          String.valueOf(limits[1]));
      }
    }
  }
}

      3、clearLimits()核心实现

                  参见如下代码注释:

private void clearLimits(ContainerId containerId) {
  if (isCpuWeightEnabled()) {
    // 删除Container对应路径和文件
    deleteCgroup(pathForCgroup(CONTROLLER_CPU, containerId.toString()));
  }
}

网友评论

登录后评论
0/500
评论
柏辰爸爸
+ 关注