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/AbstractCSQueue.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/AbstractCSQueue.java index 06575be4c7..250fcc716d 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/AbstractCSQueue.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/AbstractCSQueue.java @@ -18,25 +18,15 @@ package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity; -import java.io.IOException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.commons.lang3.StringUtils; -import org.apache.hadoop.util.Time; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.ipc.Server; import org.apache.hadoop.security.AccessControlException; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.authorize.AccessControlList; +import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting; +import org.apache.hadoop.thirdparty.com.google.common.collect.Sets; +import org.apache.hadoop.util.Time; import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.Priority; import org.apache.hadoop.yarn.api.records.QueueACL; @@ -58,13 +48,13 @@ import org.apache.hadoop.yarn.security.YarnAuthorizationProvider; import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager; import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainer; -import org.apache.hadoop.yarn.server.resourcemanager.scheduler.activities.ActivitiesManager; -import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration.AbsoluteResourceType; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.QueueResourceQuotas; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceLimits; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceUsage; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerApplicationAttempt; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerUtils; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.activities.ActivitiesManager; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration.AbsoluteResourceType; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.common.ContainerAllocationProposal; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.common.ResourceCommitRequest; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.common.SchedulerContainer; @@ -74,8 +64,17 @@ import org.apache.hadoop.yarn.util.resource.ResourceCalculator; import org.apache.hadoop.yarn.util.resource.ResourceUtils; import org.apache.hadoop.yarn.util.resource.Resources; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import org.apache.hadoop.thirdparty.com.google.common.collect.Sets; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.locks.ReentrantReadWriteLock; import static org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration.UNDEFINED; @@ -361,6 +360,10 @@ protected void setupQueueConfigs(Resource clusterResource, writeLock.lock(); try { + if (isDynamicQueue() && getParent() instanceof ParentQueue) { + ((ParentQueue) getParent()).getAutoCreatedQueueTemplate() + .setTemplateEntriesForChild(configuration, getQueuePath()); + } // get labels this.accessibleLabels = configuration.getAccessibleNodeLabels(getQueuePath()); 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/AutoCreatedQueueTemplate.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/AutoCreatedQueueTemplate.java new file mode 100644 index 0000000000..6c516c0477 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/AutoCreatedQueueTemplate.java @@ -0,0 +1,133 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *
+ * http://www.apache.org/licenses/LICENSE-2.0 + *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacitySchedulerConfiguration.AUTO_QUEUE_CREATION_V2_PREFIX;
+
+/**
+ * A handler for storing and setting auto created queue template settings.
+ */
+public class AutoCreatedQueueTemplate {
+ public static final String AUTO_QUEUE_TEMPLATE_PREFIX =
+ AUTO_QUEUE_CREATION_V2_PREFIX + "template.";
+ private static final String WILDCARD_QUEUE = "*";
+ private static final int MAX_WILDCARD_LEVEL = 1;
+
+ private final Map
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestAutoCreatedQueueTemplate {
+ private static final String TEST_QUEUE_ABC = "root.a.b.c";
+ private static final String TEST_QUEUE_AB = "root.a.b";
+ private static final String TEST_QUEUE_A = "root.a";
+ private static final String ROOT = "root";
+ private CapacitySchedulerConfiguration conf;
+
+ @Before
+ public void setUp() throws Exception {
+ conf = new CapacitySchedulerConfiguration();
+ conf.setQueues("root", new String[]{"a"});
+ conf.setQueues("a", new String[]{"b"});
+ conf.setQueues("b", new String[]{"c"});
+
+ }
+
+ @Test
+ public void testNonWildCardTemplate() {
+ conf.set(getTemplateKey(TEST_QUEUE_AB, "capacity"), "6w");
+ AutoCreatedQueueTemplate template =
+ new AutoCreatedQueueTemplate(conf, TEST_QUEUE_AB);
+ template.setTemplateEntriesForChild(conf, TEST_QUEUE_ABC);
+
+ Assert.assertEquals("weight is not set", 6f,
+ conf.getNonLabeledQueueWeight(TEST_QUEUE_ABC), 10e-6);
+
+ }
+
+ @Test
+ public void testOneLevelWildcardTemplate() {
+ conf.set(getTemplateKey("root.a.*", "capacity"), "6w");
+ AutoCreatedQueueTemplate template =
+ new AutoCreatedQueueTemplate(conf, TEST_QUEUE_AB);
+ template.setTemplateEntriesForChild(conf, TEST_QUEUE_ABC);
+
+ Assert.assertEquals("weight is not set", 6f,
+ conf.getNonLabeledQueueWeight(TEST_QUEUE_ABC), 10e-6);
+
+ }
+
+ @Test
+ public void testIgnoredWhenRootWildcarded() {
+ conf.set(getTemplateKey("*", "capacity"), "6w");
+ AutoCreatedQueueTemplate template =
+ new AutoCreatedQueueTemplate(conf, ROOT);
+ template.setTemplateEntriesForChild(conf, TEST_QUEUE_A);
+
+ Assert.assertEquals("weight is set", -1f,
+ conf.getNonLabeledQueueWeight(TEST_QUEUE_A), 10e-6);
+ }
+
+ @Test
+ public void testIgnoredWhenNoParent() {
+ conf.set(getTemplateKey("root", "capacity"), "6w");
+ AutoCreatedQueueTemplate template =
+ new AutoCreatedQueueTemplate(conf, ROOT);
+ template.setTemplateEntriesForChild(conf, ROOT);
+
+ Assert.assertEquals("weight is set", -1f,
+ conf.getNonLabeledQueueWeight(ROOT), 10e-6);
+ }
+
+ @Test
+ public void testTemplatePrecedence() {
+ conf.set(getTemplateKey("root.a.b", "capacity"), "6w");
+ conf.set(getTemplateKey("root.a.*", "capacity"), "4w");
+ conf.set(getTemplateKey("root.*.*", "capacity"), "2w");
+
+ AutoCreatedQueueTemplate template =
+ new AutoCreatedQueueTemplate(conf, TEST_QUEUE_AB);
+ template.setTemplateEntriesForChild(conf, TEST_QUEUE_ABC);
+
+ Assert.assertEquals(
+ "explicit template does not have the highest precedence", 6f,
+ conf.getNonLabeledQueueWeight(TEST_QUEUE_ABC), 10e-6);
+
+ CapacitySchedulerConfiguration newConf =
+ new CapacitySchedulerConfiguration();
+ newConf.set(getTemplateKey("root.a.*", "capacity"), "4w");
+ template =
+ new AutoCreatedQueueTemplate(newConf, TEST_QUEUE_AB);
+ template.setTemplateEntriesForChild(newConf, TEST_QUEUE_ABC);
+
+ Assert.assertEquals("precedence is invalid", 4f,
+ newConf.getNonLabeledQueueWeight(TEST_QUEUE_ABC), 10e-6);
+ }
+
+ private String getTemplateKey(String queuePath, String entryKey) {
+ return CapacitySchedulerConfiguration.getQueuePrefix(queuePath)
+ + AutoCreatedQueueTemplate.AUTO_QUEUE_TEMPLATE_PREFIX + entryKey;
+ }
+}
\ No newline at end of file
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/TestCapacitySchedulerNewQueueAutoCreation.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/TestCapacitySchedulerNewQueueAutoCreation.java
index 4dae4fd64e..c514fc7af2 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/TestCapacitySchedulerNewQueueAutoCreation.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/TestCapacitySchedulerNewQueueAutoCreation.java
@@ -18,6 +18,7 @@
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
+import org.apache.hadoop.yarn.api.records.QueueState;
import org.apache.hadoop.test.GenericTestUtils;
import org.apache.hadoop.util.Time;
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
@@ -647,6 +648,85 @@ public void testAutoCreateQueueMaxQueuesLimit() throws Exception {
}
}
+ @Test
+ public void testAutoCreatedQueueTemplateConfig() throws Exception {
+ startScheduler();
+ csConf.set(AutoCreatedQueueTemplate.getAutoQueueTemplatePrefix(
+ "root.a.*") + "capacity", "6w");
+ cs.reinitialize(csConf, mockRM.getRMContext());
+
+ LeafQueue a2 = createQueue("root.a.a-auto.a2");
+ Assert.assertEquals("weight is not set by template", 6f,
+ a2.getQueueCapacities().getWeight(), 1e-6);
+
+ cs.reinitialize(csConf, mockRM.getRMContext());
+ a2 = (LeafQueue) cs.getQueue("root.a.a-auto.a2");
+ Assert.assertEquals("weight is overridden", 6f,
+ a2.getQueueCapacities().getWeight(), 1e-6);
+
+ csConf.setNonLabeledQueueWeight("root.a.a-auto.a2", 4f);
+ cs.reinitialize(csConf, mockRM.getRMContext());
+ Assert.assertEquals("weight is not explicitly set", 4f,
+ a2.getQueueCapacities().getWeight(), 1e-6);
+ }
+
+ @Test
+ public void testAutoCreatedQueueConfigChange() throws Exception {
+ startScheduler();
+ LeafQueue a2 = createQueue("root.a.a-auto.a2");
+ csConf.setNonLabeledQueueWeight("root.a.a-auto.a2", 4f);
+ cs.reinitialize(csConf, mockRM.getRMContext());
+
+ Assert.assertEquals("weight is not explicitly set", 4f,
+ a2.getQueueCapacities().getWeight(), 1e-6);
+
+ a2 = (LeafQueue) cs.getQueue("root.a.a-auto.a2");
+ csConf.setState("root.a.a-auto.a2", QueueState.STOPPED);
+ cs.reinitialize(csConf, mockRM.getRMContext());
+ Assert.assertEquals("root.a.a-auto.a2 has not been stopped",
+ QueueState.STOPPED, a2.getState());
+
+ csConf.setState("root.a.a-auto.a2", QueueState.RUNNING);
+ cs.reinitialize(csConf, mockRM.getRMContext());
+ Assert.assertEquals("root.a.a-auto.a2 is not running",
+ QueueState.RUNNING, a2.getState());
+ }
+
+ @Test
+ public void testAutoCreateQueueState() throws Exception {
+ startScheduler();
+
+ createQueue("root.e.e1");
+ csConf.setState("root.e", QueueState.STOPPED);
+ csConf.setState("root.e.e1", QueueState.STOPPED);
+ csConf.setState("root.a", QueueState.STOPPED);
+ cs.reinitialize(csConf, mockRM.getRMContext());
+
+ // Make sure the static queue is stopped
+ Assert.assertEquals(cs.getQueue("root.a").getState(),
+ QueueState.STOPPED);
+ // If not set, default is the queue state of parent
+ Assert.assertEquals(cs.getQueue("root.a.a1").getState(),
+ QueueState.STOPPED);
+
+ Assert.assertEquals(cs.getQueue("root.e").getState(),
+ QueueState.STOPPED);
+ Assert.assertEquals(cs.getQueue("root.e.e1").getState(),
+ QueueState.STOPPED);
+
+ // Make root.e state to RUNNING
+ csConf.setState("root.e", QueueState.RUNNING);
+ cs.reinitialize(csConf, mockRM.getRMContext());
+ Assert.assertEquals(cs.getQueue("root.e.e1").getState(),
+ QueueState.STOPPED);
+
+ // Make root.e.e1 state to RUNNING
+ csConf.setState("root.e.e1", QueueState.RUNNING);
+ cs.reinitialize(csConf, mockRM.getRMContext());
+ Assert.assertEquals(cs.getQueue("root.e.e1").getState(),
+ QueueState.RUNNING);
+ }
+
@Test
public void testAutoQueueCreationDepthLimitFromStaticParent()
throws Exception {