diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java index 6a90079..a95397a 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java @@ -437,6 +437,16 @@ public static final String NM_PMEM_MB = NM_PREFIX + "resource.memory-mb"; public static final int DEFAULT_NM_PMEM_MB = 8 * 1024; + /** Specifies whether physical memory check is enabled. */ + public static final String NM_PMEM_CHECK_ENABLED = NM_PREFIX + + "pmem-check-enabled"; + public static final boolean DEFAULT_NM_PMEM_CHECK_ENABLED = true; + + /** Specifies whether physical memory check is enabled. */ + public static final String NM_VMEM_CHECK_ENABLED = NM_PREFIX + + "vmem-check-enabled"; + public static final boolean DEFAULT_NM_VMEM_CHECK_ENABLED = true; + /** Conversion ratio for physical memory to virtual memory. */ public static final String NM_VMEM_PMEM_RATIO = NM_PREFIX + "vmem-pmem-ratio"; diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainersMonitorImpl.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainersMonitorImpl.java index d73f52c..8e098d3 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainersMonitorImpl.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/ContainersMonitorImpl.java @@ -105,42 +105,54 @@ public synchronized void init(Configuration conf) { + this.processTreeClass); long totalPhysicalMemoryOnNM = DISABLED_MEMORY_LIMIT; - if (this.resourceCalculatorPlugin != null) { - totalPhysicalMemoryOnNM = - this.resourceCalculatorPlugin.getPhysicalMemorySize(); - if (totalPhysicalMemoryOnNM <= 0) { - LOG.warn("NodeManager's totalPmem could not be calculated. " - + "Setting it to " + DISABLED_MEMORY_LIMIT); - totalPhysicalMemoryOnNM = DISABLED_MEMORY_LIMIT; + long configuredPMemForContainers = conf.getLong( + YarnConfiguration.NM_PMEM_MB, + YarnConfiguration.DEFAULT_NM_PMEM_MB) * 1024 * 1024; + if (conf.getBoolean(YarnConfiguration.NM_PMEM_CHECK_ENABLED, + YarnConfiguration.DEFAULT_NM_PMEM_CHECK_ENABLED)) { + + // ///////// Physical memory configuration ////// + this.maxPmemAllottedForContainers = configuredPMemForContainers; + + // Logging if actual pmem cannot be determined. + if (this.resourceCalculatorPlugin != null) { + totalPhysicalMemoryOnNM = this.resourceCalculatorPlugin + .getPhysicalMemorySize(); + if (totalPhysicalMemoryOnNM <= 0) { + LOG.warn("NodeManager's totalPmem could not be calculated. " + + "Setting it to " + DISABLED_MEMORY_LIMIT); + totalPhysicalMemoryOnNM = DISABLED_MEMORY_LIMIT; + } } - } - // ///////// Physical memory configuration ////// - this.maxPmemAllottedForContainers = - conf.getLong(YarnConfiguration.NM_PMEM_MB, YarnConfiguration.DEFAULT_NM_PMEM_MB); - this.maxPmemAllottedForContainers = - this.maxPmemAllottedForContainers * 1024 * 1024L; //Normalize to bytes - - if (totalPhysicalMemoryOnNM != DISABLED_MEMORY_LIMIT && - this.maxPmemAllottedForContainers > - totalPhysicalMemoryOnNM * 0.80f) { - LOG.warn("NodeManager configured with " + - TraditionalBinaryPrefix.long2String(maxPmemAllottedForContainers, "", 1) + - " physical memory allocated to containers, which is more than " + - "80% of the total physical memory available (" + - TraditionalBinaryPrefix.long2String(totalPhysicalMemoryOnNM, "", 1) + - "). Thrashing might happen."); + if (totalPhysicalMemoryOnNM != DISABLED_MEMORY_LIMIT + && this.maxPmemAllottedForContainers > totalPhysicalMemoryOnNM * 0.80f) { + LOG.warn("NodeManager configured with " + + TraditionalBinaryPrefix.long2String(maxPmemAllottedForContainers, + "", 1) + + " physical memory allocated to containers, which is more than " + + "80% of the total physical memory available (" + + TraditionalBinaryPrefix.long2String(totalPhysicalMemoryOnNM, "", + 1) + "). Thrashing might happen."); + } + } else { + LOG.info("Physical memory check disabled."); + this.maxPmemAllottedForContainers = DISABLED_MEMORY_LIMIT; } - // ///////// Virtual memory configuration ////// - float vmemRatio = conf.getFloat( - YarnConfiguration.NM_VMEM_PMEM_RATIO, - YarnConfiguration.DEFAULT_NM_VMEM_PMEM_RATIO); - Preconditions.checkArgument(vmemRatio > 0.99f, - YarnConfiguration.NM_VMEM_PMEM_RATIO + - " should be at least 1.0"); - this.maxVmemAllottedForContainers = - (long)(vmemRatio * maxPmemAllottedForContainers); + if (conf.getBoolean(YarnConfiguration.NM_VMEM_CHECK_ENABLED, + YarnConfiguration.DEFAULT_NM_VMEM_CHECK_ENABLED)) { + // ///////// Virtual memory configuration ////// + float vmemRatio = conf.getFloat(YarnConfiguration.NM_VMEM_PMEM_RATIO, + YarnConfiguration.DEFAULT_NM_VMEM_PMEM_RATIO); + Preconditions.checkArgument(vmemRatio > 0.99f, + YarnConfiguration.NM_VMEM_PMEM_RATIO + " should be at least 1.0"); + this.maxVmemAllottedForContainers = + (long) (vmemRatio * configuredPMemForContainers); + } else { + LOG.info("Virtual memory check disabled."); + this.maxVmemAllottedForContainers = DISABLED_MEMORY_LIMIT; + } super.init(conf); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/TestContainersMonitor.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/TestContainersMonitor.java index 41456fd..0427c94 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/TestContainersMonitor.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/monitor/TestContainersMonitor.java @@ -20,6 +20,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; import java.io.BufferedReader; import java.io.File; @@ -52,8 +54,11 @@ import org.apache.hadoop.yarn.api.records.Resource; import org.apache.hadoop.yarn.api.records.URL; import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.apache.hadoop.yarn.event.AsyncDispatcher; +import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor; import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor.ExitCode; import org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor.Signal; +import org.apache.hadoop.yarn.server.nodemanager.Context; import org.apache.hadoop.yarn.server.nodemanager.containermanager.BaseContainerManagerTest; import org.apache.hadoop.yarn.util.ConverterUtils; import org.apache.hadoop.yarn.util.LinuxResourceCalculatorPlugin; @@ -281,4 +286,48 @@ public void testContainerKillOnMemoryOverflow() throws IOException, exec.signalContainer(user, pid, Signal.NULL)); } + + @Test(timeout = 20000) + public void testContainerMonitorMemFlags() { + ContainersMonitor cm = null; + + cm = new ContainersMonitorImpl(mock(ContainerExecutor.class), + mock(AsyncDispatcher.class), mock(Context.class)); + cm.init(getConfForCM(false, false, 8192, 2.1f)); + assertEquals(ContainersMonitorImpl.DISABLED_MEMORY_LIMIT, + cm.getPmemAllocatedForContainers()); + assertEquals(ContainersMonitorImpl.DISABLED_MEMORY_LIMIT, + cm.getVmemAllocatedForContainers()); + + cm = new ContainersMonitorImpl(mock(ContainerExecutor.class), + mock(AsyncDispatcher.class), mock(Context.class)); + cm.init(getConfForCM(true, false, 8192, 2.1f)); + assertEquals(8192 * 1024 * 1024l, cm.getPmemAllocatedForContainers()); + assertEquals(ContainersMonitorImpl.DISABLED_MEMORY_LIMIT, + cm.getVmemAllocatedForContainers()); + + cm = new ContainersMonitorImpl(mock(ContainerExecutor.class), + mock(AsyncDispatcher.class), mock(Context.class)); + cm.init(getConfForCM(true, true, 8192, 2.1f)); + assertEquals(8192 * 1024 * 1024l, cm.getPmemAllocatedForContainers()); + assertEquals((long) (8192l * 1024l * 1024l * 2.1f), + cm.getVmemAllocatedForContainers()); + + cm = new ContainersMonitorImpl(mock(ContainerExecutor.class), + mock(AsyncDispatcher.class), mock(Context.class)); + cm.init(getConfForCM(false, true, 8192, 2.1f)); + assertEquals(ContainersMonitorImpl.DISABLED_MEMORY_LIMIT, + cm.getPmemAllocatedForContainers()); + assertEquals((long) (8192l * 1024l * 1024l * 2.1f), + cm.getVmemAllocatedForContainers()); + } + + private YarnConfiguration getConfForCM(boolean pMemEnabled, boolean vMemEnabled, int nmPmem, float vMemToPMemRatio) { + YarnConfiguration conf = new YarnConfiguration(); + conf.setInt(YarnConfiguration.NM_PMEM_MB, nmPmem); + conf.setBoolean(YarnConfiguration.NM_PMEM_CHECK_ENABLED, pMemEnabled); + conf.setBoolean(YarnConfiguration.NM_VMEM_CHECK_ENABLED, vMemEnabled); + conf.setFloat(YarnConfiguration.NM_VMEM_PMEM_RATIO, vMemToPMemRatio); + return conf; + } }