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 2f6ca5a1597..db8479d2940 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 @@ -1528,7 +1528,10 @@ private Resource getMinResourceNormalized(String name, } void updateMaxAppRelatedField(CapacitySchedulerConfiguration conf, - LeafQueue leafQueue, String label) { + LeafQueue leafQueue) { + String label = getDefaultNodeLabelExpression() == null ? RMNodeLabelsManager.NO_LABEL + : getDefaultNodeLabelExpression(); + int maxApplications = conf.getMaximumApplicationsPerQueue(queuePath); if (maxApplications < 0) { int maxGlobalPerQueueApps = conf.getGlobalMaximumApplicationsPerQueue(); @@ -1643,11 +1646,6 @@ void updateEffectiveResources(Resource clusterResource) { deriveCapacityFromAbsoluteConfigurations(label, clusterResource, rc); // Re-visit max applications for a queue based on absolute capacity if // needed. - if (this instanceof LeafQueue) { - LeafQueue leafQueue = (LeafQueue) this; - CapacitySchedulerConfiguration conf = csContext.getConfiguration(); - updateMaxAppRelatedField(conf, leafQueue, label); - } } else{ queueResourceQuotas.setEffectiveMinResource(label, Resources .multiply(resourceByLabel, 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/CapacitySchedulerQueueManager.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/CapacitySchedulerQueueManager.java index e5b41cede3a..a26fadf4342 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/CapacitySchedulerQueueManager.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/CapacitySchedulerQueueManager.java @@ -632,6 +632,11 @@ public ConfiguredNodeLabels getConfiguredNodeLabels() { return configuredNodeLabels; } + @VisibleForTesting + public void reinitConfiguredNodeLabels(CapacitySchedulerConfiguration conf) { + this.configuredNodeLabels = new ConfiguredNodeLabels(conf); + } + private LeafQueue createAutoQueue(ApplicationPlacementContext queue) throws SchedulerDynamicEditException { List parentsToCreate = determineMissingParents(queue); 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/LeafQueue.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/LeafQueue.java index 19de6db21b7..44727fb1db1 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/LeafQueue.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/LeafQueue.java @@ -1945,14 +1945,9 @@ public void updateClusterResource(Resource clusterResource, updateAbsoluteCapacities(); - // If maxApplications not set, use the system total max app, apply newly - // calculated abs capacity of the queue. - // When add new queue, the parent queue's other children should also - // update the max app. - super.updateMaxAppRelatedField(csContext.getConfiguration(), - this, CommonNodeLabelsManager.NO_LABEL); - super.updateEffectiveResources(clusterResource); + super.updateMaxAppRelatedField(csContext.getConfiguration(), + this); updateCurrentResourceLimits(currentResourceLimits, clusterResource); 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/TestLeafQueue.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/TestLeafQueue.java index b6cc132da53..61f4e613c8c 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/TestLeafQueue.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/TestLeafQueue.java @@ -5120,6 +5120,36 @@ private ApplicationAttemptId createAppAttemptId(int appId, int attemptId) { return queue; } + @Test + public void testMaxApplicationsWithNodeLabels() throws IOException { + CapacitySchedulerConfiguration conf = csConf; + String rootChild = root.getChildQueues().get(0).getQueuePath(); + + conf.setCapacityByLabel(ROOT, "test", 100); + conf.setCapacityByLabel( rootChild, "test", 100); + conf.setCapacityByLabel( rootChild + "." + A, "test", 20); + conf.setCapacityByLabel( rootChild + "." + B, "test", 40); + conf.setCapacityByLabel( rootChild + "." + C, "test", 10); + conf.setCapacityByLabel( rootChild + "." + C + "." + C1, "test", 100); + conf.setCapacityByLabel( rootChild + "." + D, "test", 30); + conf.setCapacityByLabel( rootChild + "." + E, "test", 0); + cs.getCapacitySchedulerQueueManager().reinitConfiguredNodeLabels(conf); + cs.setMaxRunningAppsEnforcer(new CSMaxRunningAppsEnforcer(cs)); + cs.reinitialize(conf, cs.getRMContext()); + + LeafQueue e = (LeafQueue) cs.getQueue("e"); + // Check maximum applications when default-node-label-expression is not set (defaults to NO_LABEL) + Assert.assertEquals("Maximum application calculation is wrong when no default-node-label-expression is set", + (int)(conf.getMaximumSystemApplications() * e.getAbsoluteCapacity()), e.getMaxApplications()); + + conf.setDefaultNodeLabelExpression(rootChild + "." + E, "test"); + cs.reinitialize(conf, cs.getRMContext()); + + e = (LeafQueue) cs.getQueue("e"); + Assert.assertEquals("Maximum application calculation is wrong when default-node-label-expression is set", + 0, e.getMaxApplications()); + } + @After public void tearDown() throws Exception { if (cs != null) { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/CapacityScheduler.md b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/CapacityScheduler.md index 1dec2da113e..d87f2be9af6 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/CapacityScheduler.md +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/CapacityScheduler.md @@ -141,7 +141,7 @@ Configuration | Property | Description | |:---- |:---- | -| `yarn.scheduler.capacity.maximum-applications` / `yarn.scheduler.capacity..maximum-applications` | Maximum number of applications in the system which can be concurrently active both running and pending. Limits on each queue are directly proportional to their queue capacities and user limits. This is a hard limit and any applications submitted when this limit is reached will be rejected. Default is 10000. This can be set for all queues with `yarn.scheduler.capacity.maximum-applications` and can also be overridden on a per queue basis by setting `yarn.scheduler.capacity..maximum-applications`. Integer value expected. | +| `yarn.scheduler.capacity.maximum-applications` / `yarn.scheduler.capacity..maximum-applications` | Maximum number of applications in the system which can be concurrently active both running and pending. Limits on each queue are directly proportional to their queue capacities and user limits. This is a hard limit and any applications submitted when this limit is reached will be rejected. Default is 10000. This can be set for all queues with `yarn.scheduler.capacity.maximum-applications` and can also be overridden on a per queue basis by setting `yarn.scheduler.capacity..maximum-applications`. When this property is not set for a specific queue path, the actual value of the maximum application is calculated by the queue's absolute capacity for the corresponding node label set in default-node-label-expression (which defaults to the empty node label). Integer value expected. | | `yarn.scheduler.capacity.maximum-am-resource-percent` / `yarn.scheduler.capacity..maximum-am-resource-percent` | Maximum percent of resources in the cluster which can be used to run application masters - controls number of concurrent active applications. Limits on each queue are directly proportional to their queue capacities and user limits. Specified as a float - ie 0.5 = 50%. Default is 10%. This can be set for all queues with `yarn.scheduler.capacity.maximum-am-resource-percent` and can also be overridden on a per queue basis by setting `yarn.scheduler.capacity..maximum-am-resource-percent` | | `yarn.scheduler.capacity.max-parallel-apps` / `yarn.scheduler.capacity..max-parallel-apps` | Maximum number of applications that can run at the same time. Unlike to `maximum-applications`, application submissions are *not* rejected when this limit is reached. Instead they stay in `ACCEPTED` state until they are eligible to run. This can be set for all queues with `yarn.scheduler.capacity.max-parallel-apps` and can also be overridden on a per queue basis by setting `yarn.scheduler.capacity..max-parallel-apps`. Integer value is expected. By default, there is no limit. |