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