From 910cb6b887c73641d8eadd79249dfaa852edd809 Mon Sep 17 00:00:00 2001
From: Peter Szucs <116345192+p-szucs@users.noreply.github.com>
Date: Tue, 30 Apr 2024 11:25:16 +0200
Subject: [PATCH] YARN-11685. Create a config to enable/disable cgroup v2
functionality (#6770)
---
.../hadoop/yarn/conf/YarnConfiguration.java | 8 +++
.../src/main/resources/yarn-default.xml | 6 ++
.../resources/ResourceHandlerModule.java | 46 +++++++++----
.../resources/TestResourceHandlerModule.java | 68 +++++++++++++++++++
4 files changed, 115 insertions(+), 13 deletions(-)
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 650e82d673..d96cfe9150 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
@@ -2804,6 +2804,14 @@ public static boolean isAclEnabled(Configuration conf) {
public static final long DEFAULT_NM_LINUX_CONTAINER_CGROUPS_DELETE_DELAY =
20;
+ /**
+ * Boolean indicating whether cgroup v2 is enabled.
+ */
+ public static final String NM_LINUX_CONTAINER_CGROUPS_V2_ENABLED =
+ NM_PREFIX + "linux-container-executor.cgroups.v2.enabled";
+
+ public static final boolean DEFAULT_NM_LINUX_CONTAINER_CGROUPS_V2_ENABLED = false;
+
/**
* Indicates if memory and CPU limits will be set for the Windows Job
* Object for the containers launched by the default container executor.
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
index 6b2d2cd817..aac840866e 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml
@@ -2464,6 +2464,12 @@
1000
+
+ yarn.nodemanager.linux-container-executor.cgroups.v2.enabled
+ false
+ Boolean indicating whether cgroup v2 is enabled.
+
+
T-file compression types used to compress aggregated logs.
yarn.nodemanager.log-aggregation.compression-type
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/resources/ResourceHandlerModule.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/resources/ResourceHandlerModule.java
index 2ee2f44af2..118013f55a 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/resources/ResourceHandlerModule.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/resources/ResourceHandlerModule.java
@@ -55,6 +55,7 @@
public class ResourceHandlerModule {
static final Logger LOG =
LoggerFactory.getLogger(ResourceHandlerModule.class);
+ private static boolean cgroupsV2Enabled;
private static volatile ResourceHandlerChain resourceHandlerChain;
/**
@@ -69,9 +70,9 @@ public class ResourceHandlerModule {
private static volatile CGroupsHandler cGroupsHandler;
private static volatile CGroupsBlkioResourceHandlerImpl
cGroupsBlkioResourceHandler;
- private static volatile CGroupsMemoryResourceHandlerImpl
+ private static volatile MemoryResourceHandler
cGroupsMemoryResourceHandler;
- private static volatile CGroupsCpuResourceHandlerImpl
+ private static volatile CpuResourceHandler
cGroupsCpuResourceHandler;
/**
@@ -82,9 +83,9 @@ private static CGroupsHandler getInitializedCGroupsHandler(Configuration conf)
if (cGroupsHandler == null) {
synchronized (CGroupsHandler.class) {
if (cGroupsHandler == null) {
- // TODO determine cgroup version
- cGroupsHandler = new CGroupsHandlerImpl(conf,
- PrivilegedOperationExecutor.getInstance(conf));
+ cGroupsHandler = cgroupsV2Enabled
+ ? new CGroupsV2HandlerImpl(conf, PrivilegedOperationExecutor.getInstance(conf))
+ : new CGroupsHandlerImpl(conf, PrivilegedOperationExecutor.getInstance(conf));
LOG.debug("Value of CGroupsHandler is: {}", cGroupsHandler);
}
}
@@ -138,7 +139,7 @@ public static String getCgroupsRelativeRoot() {
return cGroupsCpuResourceHandler;
}
- private static CGroupsCpuResourceHandlerImpl initCGroupsCpuResourceHandler(
+ private static CpuResourceHandler initCGroupsCpuResourceHandler(
Configuration conf) throws ResourceHandlerException {
boolean cgroupsCpuEnabled =
conf.getBoolean(YarnConfiguration.NM_CPU_RESOURCE_ENABLED,
@@ -152,9 +153,9 @@ private static CGroupsCpuResourceHandlerImpl initCGroupsCpuResourceHandler(
synchronized (CpuResourceHandler.class) {
if (cGroupsCpuResourceHandler == null) {
LOG.debug("Creating new cgroups cpu handler");
- cGroupsCpuResourceHandler =
- new CGroupsCpuResourceHandlerImpl(
- getInitializedCGroupsHandler(conf));
+ cGroupsCpuResourceHandler = cgroupsV2Enabled
+ ? new CGroupsV2CpuResourceHandlerImpl(getInitializedCGroupsHandler(conf))
+ : new CGroupsCpuResourceHandlerImpl(getInitializedCGroupsHandler(conf));
return cGroupsCpuResourceHandler;
}
}
@@ -256,15 +257,15 @@ public static MemoryResourceHandler initMemoryResourceHandler(
return null;
}
- private static CGroupsMemoryResourceHandlerImpl
+ private static MemoryResourceHandler
getCgroupsMemoryResourceHandler(
Configuration conf) throws ResourceHandlerException {
if (cGroupsMemoryResourceHandler == null) {
synchronized (MemoryResourceHandler.class) {
if (cGroupsMemoryResourceHandler == null) {
- cGroupsMemoryResourceHandler =
- new CGroupsMemoryResourceHandlerImpl(
- getInitializedCGroupsHandler(conf));
+ cGroupsMemoryResourceHandler = cgroupsV2Enabled
+ ? new CGroupsV2MemoryResourceHandlerImpl(getInitializedCGroupsHandler(conf))
+ : new CGroupsMemoryResourceHandlerImpl(getInitializedCGroupsHandler(conf));
}
}
}
@@ -335,6 +336,10 @@ private static void addHandlersFromConfiguredResourcePlugins(
public static ResourceHandlerChain getConfiguredResourceHandlerChain(
Configuration conf, Context nmContext) throws ResourceHandlerException {
+ cgroupsV2Enabled =
+ conf.getBoolean(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_V2_ENABLED,
+ YarnConfiguration.DEFAULT_NM_LINUX_CONTAINER_CGROUPS_V2_ENABLED);
+
if (resourceHandlerChain == null) {
synchronized (ResourceHandlerModule.class) {
if (resourceHandlerChain == null) {
@@ -355,6 +360,21 @@ static void nullifyResourceHandlerChain() throws ResourceHandlerException {
resourceHandlerChain = null;
}
+ @VisibleForTesting
+ static void resetCgroupsHandler() {
+ cGroupsHandler = null;
+ }
+
+ @VisibleForTesting
+ static void resetCpuResourceHandler() {
+ cGroupsCpuResourceHandler = null;
+ }
+
+ @VisibleForTesting
+ static void resetMemoryResourceHandler() {
+ cGroupsMemoryResourceHandler = null;
+ }
+
/**
* If a cgroup mount directory is specified, it returns cgroup directories
* with valid names.
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/resources/TestResourceHandlerModule.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/resources/TestResourceHandlerModule.java
index 171bfafc4f..9104defb92 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/resources/TestResourceHandlerModule.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/resources/TestResourceHandlerModule.java
@@ -49,6 +49,9 @@ public void setup() throws Exception {
networkEnabledConf.setBoolean(YarnConfiguration.NM_NETWORK_RESOURCE_ENABLED,
true);
ResourceHandlerModule.nullifyResourceHandlerChain();
+ ResourceHandlerModule.resetCgroupsHandler();
+ ResourceHandlerModule.resetCpuResourceHandler();
+ ResourceHandlerModule.resetMemoryResourceHandler();
}
@Test
@@ -111,4 +114,69 @@ public void testDiskResourceHandler() throws Exception {
Assert.fail("Null returned");
}
}
+
+ @Test
+ public void testCpuResourceHandlerClassForCgroupV1() throws ResourceHandlerException {
+ Configuration conf = new YarnConfiguration();
+ conf.setBoolean(YarnConfiguration.NM_CPU_RESOURCE_ENABLED, true);
+ conf.setBoolean(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_V2_ENABLED, false);
+
+ initResourceHandlerChain(conf);
+
+ Assert.assertTrue(ResourceHandlerModule.getCpuResourceHandler()
+ instanceof CGroupsCpuResourceHandlerImpl);
+ Assert.assertTrue(ResourceHandlerModule.getCGroupsHandler()
+ instanceof CGroupsHandlerImpl);
+ }
+
+ @Test
+ public void testCpuResourceHandlerClassForCgroupV2() throws ResourceHandlerException {
+ Configuration conf = new YarnConfiguration();
+ conf.setBoolean(YarnConfiguration.NM_CPU_RESOURCE_ENABLED, true);
+ conf.setBoolean(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_V2_ENABLED, true);
+
+ initResourceHandlerChain(conf);
+
+ Assert.assertTrue(ResourceHandlerModule.getCpuResourceHandler()
+ instanceof CGroupsV2CpuResourceHandlerImpl);
+ Assert.assertTrue(ResourceHandlerModule.getCGroupsHandler()
+ instanceof CGroupsV2HandlerImpl);
+ }
+
+ @Test
+ public void testMemoryResourceHandlerClassForCgroupV1() throws ResourceHandlerException {
+ Configuration conf = new YarnConfiguration();
+ conf.setBoolean(YarnConfiguration.NM_MEMORY_RESOURCE_ENABLED, true);
+ conf.setBoolean(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_V2_ENABLED, false);
+
+ initResourceHandlerChain(conf);
+
+ Assert.assertTrue(ResourceHandlerModule.getMemoryResourceHandler()
+ instanceof CGroupsMemoryResourceHandlerImpl);
+ Assert.assertTrue(ResourceHandlerModule.getCGroupsHandler()
+ instanceof CGroupsHandlerImpl);
+ }
+
+ @Test
+ public void testMemoryResourceHandlerClassForCgroupV2() throws ResourceHandlerException {
+ Configuration conf = new YarnConfiguration();
+ conf.setBoolean(YarnConfiguration.NM_MEMORY_RESOURCE_ENABLED, true);
+ conf.setBoolean(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_V2_ENABLED, true);
+
+ initResourceHandlerChain(conf);
+
+ Assert.assertTrue(ResourceHandlerModule.getMemoryResourceHandler()
+ instanceof CGroupsV2MemoryResourceHandlerImpl);
+ Assert.assertTrue(ResourceHandlerModule.getCGroupsHandler()
+ instanceof CGroupsV2HandlerImpl);
+ }
+
+ private void initResourceHandlerChain(Configuration conf) throws ResourceHandlerException {
+ ResourceHandlerChain resourceHandlerChain =
+ ResourceHandlerModule.getConfiguredResourceHandlerChain(conf,
+ mock(Context.class));
+ if (resourceHandlerChain == null) {
+ Assert.fail("Could not initialize resource handler chain");
+ }
+ }
}
\ No newline at end of file