diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java index cefbbf9..c9dbed2 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java @@ -1289,7 +1289,15 @@ public class YarnConfiguration extends Configuration { public static final boolean DEFAULT_NM_LINUX_CONTAINER_CGROUPS_STRICT_RESOURCE_USAGE = false; - + /** + * Max resource usage percent when apps not run in strict resource usage mode. + * In strict resource usage mode, apps can use resource no more than + * maxResourceUsagePercent * containerVCores + */ + public static final String NM_LINUX_CONTAINER_CGROUPS_MAX_RESOURCE_USAGE_PERCENT = + NM_PREFIX + "linux-container-executor.cgroups.max-resource-usage-percent"; + public static final float DEFAULT_NM_LINUX_CONTAINER_CGROUPS_MAX_RESOURCE_USAGE_PERCENT = + 1.2f; /** * Interval of time the linux container executor should try cleaning up diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/util/CgroupsLCEResourcesHandler.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/util/CgroupsLCEResourcesHandler.java index 6994fc3..eebb59b 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/util/CgroupsLCEResourcesHandler.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/util/CgroupsLCEResourcesHandler.java @@ -79,6 +79,8 @@ public class CgroupsLCEResourcesHandler implements LCEResourcesHandler { private long deleteCgroupTimeout; private long deleteCgroupDelay; + + private float maxResourceUsagePercentInNonstrictMode = 1.2f; // package private for testing purposes Clock clock; @@ -131,6 +133,10 @@ public class CgroupsLCEResourcesHandler implements LCEResourcesHandler { if (cgroupPrefix.charAt(len - 1) == '/') { cgroupPrefix = cgroupPrefix.substring(0, len - 1); } + + this.maxResourceUsagePercentInNonstrictMode = conf.getFloat( + YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_MAX_RESOURCE_USAGE_PERCENT, + YarnConfiguration.DEFAULT_NM_LINUX_CONTAINER_CGROUPS_MAX_RESOURCE_USAGE_PERCENT); } public void init(LinuxContainerExecutor lce) throws IOException { @@ -370,16 +376,19 @@ public class CgroupsLCEResourcesHandler implements LCEResourcesHandler { int cpuShares = CPU_DEFAULT_WEIGHT * containerVCores; updateCgroup(CONTROLLER_CPU, containerName, "shares", String.valueOf(cpuShares)); - if (strictResourceUsageMode) { - if (nodeVCores != containerVCores) { - float containerCPU = - (containerVCores * yarnProcessors) / (float) nodeVCores; - int[] limits = getOverallLimits(containerCPU); - updateCgroup(CONTROLLER_CPU, containerName, CPU_PERIOD_US, - String.valueOf(limits[0])); - updateCgroup(CONTROLLER_CPU, containerName, CPU_QUOTA_US, - String.valueOf(limits[1])); + if (nodeVCores != containerVCores) { + float containerCPU = + (containerVCores * yarnProcessors) / (float) nodeVCores; + int[] limits; + if (strictResourceUsageMode) { + limits = getOverallLimits(containerCPU); + } else { + limits = getOverallLimits(containerCPU * maxResourceUsagePercentInNonstrictMode); } + updateCgroup(CONTROLLER_CPU, containerName, CPU_PERIOD_US, + String.valueOf(limits[0])); + updateCgroup(CONTROLLER_CPU, containerName, CPU_QUOTA_US, + String.valueOf(limits[1])); } } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/util/TestCgroupsLCEResourcesHandler.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/util/TestCgroupsLCEResourcesHandler.java index cfab65c..9542c9b 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/util/TestCgroupsLCEResourcesHandler.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/util/TestCgroupsLCEResourcesHandler.java @@ -318,6 +318,26 @@ public class TestCgroupsLCEResourcesHandler { Assert.assertEquals(500 * 1000, readIntFromFile(periodFile)); Assert.assertEquals(1000 * 1000, readIntFromFile(quotaFile)); + + // 25% of CPU when non-strict mode + FileUtils.deleteQuietly(containerCpuDir); + conf.setBoolean( + YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_STRICT_RESOURCE_USAGE, + false); + conf.setFloat(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_MAX_RESOURCE_USAGE_PERCENT, + 0.5f); + handler.initConfig(); + handler.preExecute(id, + Resource.newInstance(1024, YarnConfiguration.DEFAULT_NM_VCORES / 2)); + Assert.assertTrue(containerCpuDir.exists()); + Assert.assertTrue(containerCpuDir.isDirectory()); + periodFile = new File(containerCpuDir, "cpu.cfs_period_us"); + quotaFile = new File(containerCpuDir, "cpu.cfs_quota_us"); + Assert.assertTrue(periodFile.exists()); + Assert.assertTrue(quotaFile.exists()); + Assert.assertEquals(1000 * 1000, readIntFromFile(periodFile)); + Assert.assertEquals(1000 * 1000, readIntFromFile(quotaFile)); + // CGroups set to 50% of CPU, container set to 50% of YARN CPU FileUtils.deleteQuietly(containerCpuDir); conf.setBoolean(