Sfoglia il codice sorgente

YARN-11685. Create a config to enable/disable cgroup v2 functionality (#6770)

Peter Szucs 1 anno fa
parent
commit
910cb6b887

+ 8 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java

@@ -2804,6 +2804,14 @@ public class YarnConfiguration extends Configuration {
   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.

+ 6 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml

@@ -2464,6 +2464,12 @@
     <value>1000</value>
   </property>
 
+  <property>
+    <name>yarn.nodemanager.linux-container-executor.cgroups.v2.enabled</name>
+    <value>false</value>
+    <description>Boolean indicating whether cgroup v2 is enabled.</description>
+  </property>
+
   <property>
     <description>T-file compression types used to compress aggregated logs.</description>
     <name>yarn.nodemanager.log-aggregation.compression-type</name>

+ 33 - 13
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 @@ import java.util.Set;
 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 @@ public class ResourceHandlerModule {
     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 class ResourceHandlerModule {
     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 @@ public class ResourceHandlerModule {
         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 class ResourceHandlerModule {
     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 @@ public class ResourceHandlerModule {
 
   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 @@ public class ResourceHandlerModule {
     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.

+ 68 - 0
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 class TestResourceHandlerModule {
     networkEnabledConf.setBoolean(YarnConfiguration.NM_NETWORK_RESOURCE_ENABLED,
         true);
     ResourceHandlerModule.nullifyResourceHandlerChain();
+    ResourceHandlerModule.resetCgroupsHandler();
+    ResourceHandlerModule.resetCpuResourceHandler();
+    ResourceHandlerModule.resetMemoryResourceHandler();
   }
 
   @Test
@@ -111,4 +114,69 @@ public class TestResourceHandlerModule {
       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");
+    }
+  }
 }