一、概述
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()));
}
}
|