diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CSQueueUtils.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CSQueueUtils.java index e1014c11fc8..2667fcaa020 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CSQueueUtils.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CSQueueUtils.java @@ -66,13 +66,13 @@ public static void checkAbsoluteCapacity(String queueName, private static void capacitiesSanityCheck(String queueName, QueueCapacities queueCapacities) { for (String label : queueCapacities.getExistingNodeLabels()) { - float capacity = queueCapacities.getCapacity(label); - float maximumCapacity = queueCapacities.getMaximumCapacity(label); - if (capacity > maximumCapacity) { - throw new IllegalArgumentException("Illegal queue capacity setting, " - + "(capacity=" + capacity + ") > (maximum-capacity=" - + maximumCapacity + "). When label=[" + label + "]"); - } +// float capacity = queueCapacities.getCapacity(label); +// float maximumCapacity = queueCapacities.getMaximumCapacity(label); +// if (capacity > maximumCapacity) { +// throw new IllegalArgumentException("Illegal queue capacity setting, " +// + "(capacity=" + capacity + ") > (maximum-capacity=" +// + maximumCapacity + "). When label=[" + label + "]"); +// } // Actually, this may not needed since we have verified capacity <= // maximumCapacity. And the way we compute absolute capacity (abs(x) = diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestQueueParsing.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestQueueParsing.java index 5d167c7900d..1d21668ae40 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestQueueParsing.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/TestQueueParsing.java @@ -365,7 +365,75 @@ private void setupQueueConfigurationWithLabels(CapacitySchedulerConfiguration co conf.setCapacityByLabel(B3, "red", 25); conf.setCapacityByLabel(B3, "blue", 25); } - + + private void setupQueueConfigurationWithLabelsAndRelaxCheck(CapacitySchedulerConfiguration conf) { + // Define top-level queues + conf.setQueues(CapacitySchedulerConfiguration.ROOT, new String[] {"a", "b"}); + conf.setCapacityByLabel(CapacitySchedulerConfiguration.ROOT, "red", 100); + conf.setCapacityByLabel(CapacitySchedulerConfiguration.ROOT, "blue", 100); + + final String A = CapacitySchedulerConfiguration.ROOT + ".a"; + // The cap <= max-cap check is not needed + conf.setCapacity(A, 50); + conf.setMaximumCapacity(A, 100); + + final String B = CapacitySchedulerConfiguration.ROOT + ".b"; + conf.setCapacity(B, 50); + conf.setMaximumCapacity(B, 100); + + LOG.info("Setup top-level queues"); + + // Define 2nd-level queues + final String A1 = A + ".a1"; + final String A2 = A + ".a2"; + conf.setQueues(A, new String[] {"a1", "a2"}); + conf.setAccessibleNodeLabels(A, ImmutableSet.of("red", "blue")); + conf.setCapacityByLabel(A, "red", 50); + conf.setMaximumCapacityByLabel(A, "red", 100); + conf.setCapacityByLabel(A, "blue", 30); + conf.setMaximumCapacityByLabel(A, "blue", 50); + + conf.setCapacity(A1, 60); + conf.setMaximumCapacity(A1, 60); + conf.setCapacityByLabel(A1, "red", 60); + conf.setMaximumCapacityByLabel(A1, "red", 30); + conf.setCapacityByLabel(A1, "blue", 100); + conf.setMaximumCapacityByLabel(A1, "blue", 100); + + conf.setCapacity(A2, 40); + conf.setMaximumCapacity(A2, 85); + conf.setAccessibleNodeLabels(A2, ImmutableSet.of("red")); + conf.setCapacityByLabel(A2, "red", 40); + conf.setMaximumCapacityByLabel(A2, "red", 60); + + final String B1 = B + ".b1"; + final String B2 = B + ".b2"; + final String B3 = B + ".b3"; + conf.setQueues(B, new String[] {"b1", "b2", "b3"}); + conf.setAccessibleNodeLabels(B, ImmutableSet.of("red", "blue")); + conf.setCapacityByLabel(B, "red", 50); + conf.setMaximumCapacityByLabel(B, "red", 100); + conf.setCapacityByLabel(B, "blue", 70); + conf.setMaximumCapacityByLabel(B, "blue", 100); + + conf.setCapacity(B1, 10); + conf.setMaximumCapacity(B1, 10); + conf.setCapacityByLabel(B1, "red", 60); + conf.setMaximumCapacityByLabel(B1, "red", 30); + conf.setCapacityByLabel(B1, "blue", 50); + conf.setMaximumCapacityByLabel(B1, "blue", 100); + + conf.setCapacity(B2, 80); + conf.setMaximumCapacity(B2, 40); + conf.setCapacityByLabel(B2, "red", 30); + conf.setCapacityByLabel(B2, "blue", 25); + + conf.setCapacity(B3, 10); + conf.setMaximumCapacity(B3, 25); + conf.setCapacityByLabel(B3, "red", 10); + conf.setCapacityByLabel(B3, "blue", 25); + } + private void setupQueueConfigurationWithLabelsInherit( CapacitySchedulerConfiguration conf) { // Define top-level queues @@ -472,7 +540,7 @@ private void checkQueueLabels(CapacityScheduler capacityScheduler) { // queue-B2 inherits "red"/"blue" Assert.assertTrue(capacityScheduler.getQueue("b2") .getAccessibleNodeLabels().containsAll(ImmutableSet.of("red", "blue"))); - + // check capacity of A2 CSQueue qA2 = capacityScheduler.getQueue("a2"); Assert.assertEquals(0.7, qA2.getCapacity(), DELTA); @@ -481,7 +549,7 @@ private void checkQueueLabels(CapacityScheduler capacityScheduler) { Assert.assertEquals(0.25, qA2.getQueueCapacities().getAbsoluteCapacity("red"), DELTA); Assert.assertEquals(0.1275, qA2.getAbsoluteMaximumCapacity(), DELTA); Assert.assertEquals(0.3, qA2.getQueueCapacities().getAbsoluteMaximumCapacity("red"), DELTA); - + // check capacity of B3 CSQueue qB3 = capacityScheduler.getQueue("b3"); Assert.assertEquals(0.18, qB3.getAbsoluteCapacity(), DELTA); @@ -489,7 +557,47 @@ private void checkQueueLabels(CapacityScheduler capacityScheduler) { Assert.assertEquals(0.35, qB3.getAbsoluteMaximumCapacity(), DELTA); Assert.assertEquals(1, qB3.getQueueCapacities().getAbsoluteMaximumCapacity("red"), DELTA); } - + + private void checkQueueLabelsWithLeafQueueDisableElasticity(CapacityScheduler capacityScheduler) { + // queue-A is red, blue + Assert.assertTrue(capacityScheduler.getQueue("a").getAccessibleNodeLabels() + .containsAll(ImmutableSet.of("red", "blue"))); + + // queue-A1 inherits A's configuration + Assert.assertTrue(capacityScheduler.getQueue("a1") + .getAccessibleNodeLabels().containsAll(ImmutableSet.of("red", "blue"))); + + // queue-A2 is "red" + Assert.assertEquals(1, capacityScheduler.getQueue("a2") + .getAccessibleNodeLabels().size()); + Assert.assertTrue(capacityScheduler.getQueue("a2") + .getAccessibleNodeLabels().contains("red")); + + // queue-B is "red"/"blue" + Assert.assertTrue(capacityScheduler.getQueue("b").getAccessibleNodeLabels() + .containsAll(ImmutableSet.of("red", "blue"))); + + // queue-B2 inherits "red"/"blue" + Assert.assertTrue(capacityScheduler.getQueue("b2") + .getAccessibleNodeLabels().containsAll(ImmutableSet.of("red", "blue"))); + + // check capacity of A2 + CSQueue qA2 = capacityScheduler.getQueue("a2"); + Assert.assertEquals(0.4, qA2.getCapacity(), DELTA); + Assert.assertEquals(0.4, qA2.getQueueCapacities().getCapacity("red"), DELTA); + Assert.assertEquals(0.2, qA2.getAbsoluteCapacity(), DELTA); + Assert.assertEquals(0.2, qA2.getQueueCapacities().getAbsoluteCapacity("red"), DELTA); + Assert.assertEquals(0.85, qA2.getAbsoluteMaximumCapacity(), DELTA); + Assert.assertEquals(0.6, qA2.getQueueCapacities().getAbsoluteMaximumCapacity("red"), DELTA); + + // check capacity of B3 + CSQueue qB3 = capacityScheduler.getQueue("b3"); + Assert.assertEquals(0.05, qB3.getAbsoluteCapacity(), DELTA); + Assert.assertEquals(0.05, qB3.getQueueCapacities().getAbsoluteCapacity("red"), DELTA); + Assert.assertEquals(0.25, qB3.getAbsoluteMaximumCapacity(), DELTA); + Assert.assertEquals(1, qB3.getQueueCapacities().getAbsoluteMaximumCapacity("red"), DELTA); + } + private void checkQueueLabelsInheritConfig(CapacityScheduler capacityScheduler) { // queue-A is red, blue @@ -514,7 +622,7 @@ private void checkQueueLabels(CapacityScheduler capacityScheduler) { @Test public void testQueueParsingWithLabels() throws IOException { nodeLabelManager.addToCluserNodeLabelsWithDefaultExclusivity(ImmutableSet.of("red", "blue")); - + YarnConfiguration conf = new YarnConfiguration(); CapacitySchedulerConfiguration csConf = new CapacitySchedulerConfiguration(conf); @@ -534,6 +642,30 @@ public void testQueueParsingWithLabels() throws IOException { checkQueueLabels(capacityScheduler); ServiceOperations.stopQuietly(capacityScheduler); } + + @Test + public void testQueueParsingWithLeafQueueDisableElasticity() throws IOException { + nodeLabelManager.addToCluserNodeLabelsWithDefaultExclusivity(ImmutableSet.of("red", "blue")); + + YarnConfiguration conf = new YarnConfiguration(); + CapacitySchedulerConfiguration csConf = + new CapacitySchedulerConfiguration(conf); + // setupQueueConfigurationWithLabels(csConf); + setupQueueConfigurationWithLabelsAndRelaxCheck(csConf); + CapacityScheduler capacityScheduler = new CapacityScheduler(); + RMContextImpl rmContext = + new RMContextImpl(null, null, null, null, null, null, + new RMContainerTokenSecretManager(csConf), + new NMTokenSecretManagerInRM(csConf), + new ClientToAMTokenSecretManagerInRM(), null); + rmContext.setNodeLabelManager(nodeLabelManager); + capacityScheduler.setConf(csConf); + capacityScheduler.setRMContext(rmContext); + capacityScheduler.init(csConf); + capacityScheduler.start(); + checkQueueLabelsWithLeafQueueDisableElasticity(capacityScheduler); + ServiceOperations.stopQuietly(capacityScheduler); + } @Test public void testQueueParsingWithLabelsInherit() throws IOException {