Hadoop-2.6.0中对CPU CGroups的实现,主要是通过CgroupsLCEResourcesHandler来实现的,通过它的int*()系列方法初始化一些参数和环境,比如CGroups的路径等,然后在启动容器内的可执行文
件前由LinuxContainerExecutor调用preExecute()方法,进行setupLimits()即设置限额操作,而在容器内的可执行退出后(无论成功还是失败)由LinuxContainerExecutor调用postExecute()方法,进行
clearLimits()即清除限额操作。
通过参数yarn.nodemanager.linux-container-executor.resources-handler.class配置
配置为org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler即可
参数默认值是org.apache.hadoop.yarn.server.nodemanager.util.DefaultLCEResourcesHandler。
参见如下代码注释:
<code>/*</code>
<code> </code><code>* Next three functions operate on all the resources we are enforcing.</code>
<code> </code><code>*/</code>
<code>private</code> <code>void</code> <code>setupLimits(ContainerId containerId,</code>
<code> </code><code>Resource containerResource) </code><code>throws</code> <code>IOException {</code>
<code> </code><code>String containerName = containerId.toString();</code>
<code> </code><code>if</code> <code>(isCpuWeightEnabled()) {</code>
<code> </code>
<code> </code><code>// 取container申请到资源中的VCores,注意用的是虚拟core</code>
<code> </code><code>int</code> <code>containerVCores = containerResource.getVirtualCores();</code>
<code> </code><code>// 创建CGroup,其实就是在CGroup路径中创建与CPU和容器名称相关的路径</code>
<code> </code><code>createCgroup(CONTROLLER_CPU, containerName);</code>
<code> </code><code>// 对应隔离方式(一),即shares</code>
<code> </code><code>int</code> <code>cpuShares = CPU_DEFAULT_WEIGHT * containerVCores;</code>
<code> </code><code>// 更新CGroup,其实就是在上述路径中将数值cpuShares写入shares文件</code>
<code> </code><code>// 这个cpuShares的值就是container申请到资源中的VCores * 1024</code>
<code> </code><code>updateCgroup(CONTROLLER_CPU, containerName, </code><code>"shares"</code><code>,</code>
<code> </code><code>String.valueOf(cpuShares));</code>
<code> </code><code>// 对应隔离方式(二),即cfs_period_us、cfs_quota_us</code>
<code> </code><code>// 这个是需要参数yarn.nodemanager.linux-container-executor.cgroups.strict-resource-usage设置为true的</code>
<code> </code><code>if</code> <code>(strictResourceUsageMode) {</code>
<code> </code><code>int</code> <code>nodeVCores =</code>
<code> </code><code>conf.getInt(YarnConfiguration.NM_VCORES,</code>
<code> </code><code>YarnConfiguration.DEFAULT_NM_VCORES);</code>
<code> </code><code>if</code> <code>(nodeVCores != containerVCores) {</code>
<code> </code><code>float</code> <code>containerCPU =</code>
<code> </code><code>(containerVCores * yarnProcessors) / (</code><code>float</code><code>) nodeVCores;</code>
<code> </code><code>int</code><code>[] limits = getOverallLimits(containerCPU);</code>
<code> </code>
<code> </code><code>// 更新CGroup,其实就是在上述路径中将数值limits[0]和limits[1]分别写入cfs_period_us文件和cfs_quota_us文件</code>
<code> </code><code>updateCgroup(CONTROLLER_CPU, containerName, CPU_PERIOD_US,</code>
<code> </code><code>String.valueOf(limits[</code><code>0</code><code>]));</code>
<code> </code><code>updateCgroup(CONTROLLER_CPU, containerName, CPU_QUOTA_US,</code>
<code> </code><code>String.valueOf(limits[</code><code>1</code><code>]));</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code>}</code>
<code>private</code> <code>void</code> <code>clearLimits(ContainerId containerId) {</code>
<code> </code><code>// 删除Container对应路径和文件</code>
<code> </code><code>deleteCgroup(pathForCgroup(CONTROLLER_CPU, containerId.toString()));</code>
<a target="_blank" href="http://wiki.baifendian.com/pages/viewpage.action?pageId=12824126"></a>