diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/QueueInfo.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/QueueInfo.java index 7816febb3ab..a7c1be41bba 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/QueueInfo.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/QueueInfo.java @@ -72,6 +72,24 @@ public static QueueInfo newInstance(String queueName, float capacity, return queueInfo; } + @Private + @Unstable + public static QueueInfo newInstance(String queueName, float capacity, + float maximumCapacity, float currentCapacity, + List childQueues, List applications, + QueueState queueState, Set accessibleNodeLabels, + String defaultNodeLabelExpression, QueueStatistics queueStatistics, + boolean preemptionDisabled, boolean intraQueuePreemptionDisabled) { + QueueInfo queueInfo = QueueInfo.newInstance(queueName, capacity, + maximumCapacity, currentCapacity, + childQueues, applications, + queueState, accessibleNodeLabels, + defaultNodeLabelExpression, queueStatistics, + preemptionDisabled); + queueInfo.setIntraQueuePreemptionDisabled(intraQueuePreemptionDisabled); + return queueInfo; + } + /** * Get the name of the queue. * @return name of the queue @@ -219,4 +237,18 @@ public abstract void setDefaultNodeLabelExpression( @Private @Unstable public abstract void setPreemptionDisabled(boolean preemptionDisabled); + + /** + * Get the intra-queue preemption status of the queue. + * @return if property is not in proto, return null; + * otherwise, return intra-queue preemption status of the queue + */ + @Public + @Stable + public abstract Boolean getIntraQueuePreemptionDisabled(); + + @Private + @Unstable + public abstract void setIntraQueuePreemptionDisabled( + boolean intraQueuePreemptionDisabled); } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto index 8c847b2ce4a..16e7c5b8ace 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto @@ -424,6 +424,7 @@ message QueueInfoProto { optional string defaultNodeLabelExpression = 9; optional QueueStatisticsProto queueStatistics = 10; optional bool preemptionDisabled = 11; + optional bool intraQueuePreemptionDisabled = 12; } enum QueueACLProto { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/QueueCLI.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/QueueCLI.java index 330b081c73a..2c3dfd01bfc 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/QueueCLI.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/QueueCLI.java @@ -158,5 +158,11 @@ private void printQueueInfo(PrintWriter writer, QueueInfo queueInfo) { writer.print("\tPreemption : "); writer.println(preemptStatus ? "disabled" : "enabled"); } + + Boolean intraQueuePreemption = queueInfo.getIntraQueuePreemptionDisabled(); + if (intraQueuePreemption != null) { + writer.print("\tIntra-queue Preemption : "); + writer.println(intraQueuePreemption ? "disabled" : "enabled"); + } } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/ProtocolHATestBase.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/ProtocolHATestBase.java index c9a0fc7988f..660a4ef9839 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/ProtocolHATestBase.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/ProtocolHATestBase.java @@ -664,7 +664,8 @@ public YarnClusterMetrics createFakeYarnClusterMetrics() { public QueueInfo createFakeQueueInfo() { return QueueInfo.newInstance("root", 100f, 100f, 50f, null, - createFakeAppReports(), QueueState.RUNNING, null, null, null, false); + createFakeAppReports(), QueueState.RUNNING, null, null, null, false, + false); } public List createFakeQueueUserACLInfoList() { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java index c8fd19c2301..86fd6d6eca7 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java @@ -1466,7 +1466,7 @@ public void testGetQueueInfo() throws Exception { nodeLabels.add("GPU"); nodeLabels.add("JDK_7"); QueueInfo queueInfo = QueueInfo.newInstance("queueA", 0.4f, 0.8f, 0.5f, - null, null, QueueState.RUNNING, nodeLabels, "GPU", null, false); + null, null, QueueState.RUNNING, nodeLabels, "GPU", null, false, false); when(client.getQueueInfo(any(String.class))).thenReturn(queueInfo); int result = cli.run(new String[] { "-status", "queueA" }); assertEquals(0, result); @@ -1482,13 +1482,14 @@ public void testGetQueueInfo() throws Exception { pw.println("\tDefault Node Label expression : " + "GPU"); pw.println("\tAccessible Node Labels : " + "JDK_7,GPU"); pw.println("\tPreemption : " + "enabled"); + pw.println("\tIntra-queue Preemption : " + "enabled"); pw.close(); String queueInfoStr = baos.toString("UTF-8"); Assert.assertEquals(queueInfoStr, sysOutStream.toString()); } @Test - public void testGetQueueInfoPreemptionEnabled() throws Exception { + public void testGetQueueInfoOverrideIntraQueuePreemption() throws Exception { CapacitySchedulerConfiguration conf = new CapacitySchedulerConfiguration(); ReservationSystemTestUtil.setupQueueConfiguration(conf); conf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class, @@ -1497,9 +1498,80 @@ public void testGetQueueInfoPreemptionEnabled() throws Exception { conf.set(YarnConfiguration.RM_SCHEDULER_MONITOR_POLICIES, "org.apache.hadoop.yarn.server.resourcemanager.monitor.capacity." + "ProportionalCapacityPreemptionPolicy"); + // Turn on cluster-wide intra-queue preemption + conf.setBoolean( + CapacitySchedulerConfiguration.INTRAQUEUE_PREEMPTION_ENABLED, true); + // Disable intra-queue preemption for all queues + conf.setBoolean(CapacitySchedulerConfiguration.PREFIX + + "root.intra-queue-preemption.disable_preemption", true); + // Enable intra-queue preemption for the a1 queue + conf.setBoolean(CapacitySchedulerConfiguration.PREFIX + + "root.a.a1.intra-queue-preemption.disable_preemption", false); + MiniYARNCluster cluster = + new MiniYARNCluster("testGetQueueInfoOverrideIntraQueuePreemption", + 2, 1, 1); + + YarnClient yarnClient = null; + try { + cluster.init(conf); + cluster.start(); + final Configuration yarnConf = cluster.getConfig(); + yarnClient = YarnClient.createYarnClient(); + yarnClient.init(yarnConf); + yarnClient.start(); + + QueueCLI cli = new QueueCLI(); + cli.setClient(yarnClient); + cli.setSysOutPrintStream(sysOut); + cli.setSysErrPrintStream(sysErr); + sysOutStream.reset(); + // Get status for the root.a queue + int result = cli.run(new String[] { "-status", "a" }); + assertEquals(0, result); + String queueStatusOut = sysOutStream.toString(); + Assert.assertTrue(queueStatusOut + .contains("\tPreemption : enabled")); + // In-queue preemption is disabled at the "root.a" queue level + Assert.assertTrue(queueStatusOut + .contains("Intra-queue Preemption : disabled")); + cli = new QueueCLI(); + cli.setClient(yarnClient); + cli.setSysOutPrintStream(sysOut); + cli.setSysErrPrintStream(sysErr); + sysOutStream.reset(); + // Get status for the root.a.a1 queue + result = cli.run(new String[] { "-status", "a1" }); + assertEquals(0, result); + queueStatusOut = sysOutStream.toString(); + Assert.assertTrue(queueStatusOut + .contains("\tPreemption : enabled")); + // In-queue preemption is enabled at the "root.a.a1" queue level + Assert.assertTrue(queueStatusOut + .contains("Intra-queue Preemption : enabled")); + } finally { + // clean-up + if (yarnClient != null) { + yarnClient.stop(); + } + cluster.stop(); + cluster.close(); + } + } + + @Test + public void testGetQueueInfoPreemptionEnabled() throws Exception { + CapacitySchedulerConfiguration conf = new CapacitySchedulerConfiguration(); + ReservationSystemTestUtil.setupQueueConfiguration(conf); + conf.setClass(YarnConfiguration.RM_SCHEDULER, CapacityScheduler.class, + ResourceScheduler.class); conf.setBoolean(YarnConfiguration.RM_SCHEDULER_ENABLE_MONITORS, true); + conf.set(YarnConfiguration.RM_SCHEDULER_MONITOR_POLICIES, + "org.apache.hadoop.yarn.server.resourcemanager.monitor.capacity." + + "ProportionalCapacityPreemptionPolicy"); + conf.setBoolean( + CapacitySchedulerConfiguration.INTRAQUEUE_PREEMPTION_ENABLED, true); MiniYARNCluster cluster = - new MiniYARNCluster("testReservationAPIs", 2, 1, 1); + new MiniYARNCluster("testGetQueueInfoPreemptionEnabled", 2, 1, 1); YarnClient yarnClient = null; try { @@ -1517,8 +1589,11 @@ public void testGetQueueInfoPreemptionEnabled() throws Exception { sysOutStream.reset(); int result = cli.run(new String[] { "-status", "a1" }); assertEquals(0, result); - Assert.assertTrue(sysOutStream.toString() - .contains("Preemption : enabled")); + String queueStatusOut = sysOutStream.toString(); + Assert.assertTrue(queueStatusOut + .contains("\tPreemption : enabled")); + Assert.assertTrue(queueStatusOut + .contains("Intra-queue Preemption : enabled")); } finally { // clean-up if (yarnClient != null) { @@ -1559,8 +1634,11 @@ public void testGetQueueInfoPreemptionDisabled() throws Exception { sysOutStream.reset(); int result = cli.run(new String[] { "-status", "a1" }); assertEquals(0, result); - Assert.assertTrue(sysOutStream.toString() - .contains("Preemption : disabled")); + String queueStatusOut = sysOutStream.toString(); + Assert.assertTrue(queueStatusOut + .contains("\tPreemption : disabled")); + Assert.assertTrue(queueStatusOut + .contains("Intra-queue Preemption : disabled")); } } @@ -1568,7 +1646,7 @@ public void testGetQueueInfoPreemptionDisabled() throws Exception { public void testGetQueueInfoWithEmptyNodeLabel() throws Exception { QueueCLI cli = createAndGetQueueCLI(); QueueInfo queueInfo = QueueInfo.newInstance("queueA", 0.4f, 0.8f, 0.5f, - null, null, QueueState.RUNNING, null, null, null, true); + null, null, QueueState.RUNNING, null, null, null, true, true); when(client.getQueueInfo(any(String.class))).thenReturn(queueInfo); int result = cli.run(new String[] { "-status", "queueA" }); assertEquals(0, result); @@ -1585,6 +1663,7 @@ public void testGetQueueInfoWithEmptyNodeLabel() throws Exception { + NodeLabel.DEFAULT_NODE_LABEL_PARTITION); pw.println("\tAccessible Node Labels : "); pw.println("\tPreemption : " + "disabled"); + pw.println("\tIntra-queue Preemption : " + "disabled"); pw.close(); String queueInfoStr = baos.toString("UTF-8"); Assert.assertEquals(queueInfoStr, sysOutStream.toString()); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/QueueInfoPBImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/QueueInfoPBImpl.java index 605cab161cc..4e70378f3f0 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/QueueInfoPBImpl.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/QueueInfoPBImpl.java @@ -408,4 +408,18 @@ public void setPreemptionDisabled(boolean preemptionDisabled) { maybeInitBuilder(); builder.setPreemptionDisabled(preemptionDisabled); } + + @Override + public Boolean getIntraQueuePreemptionDisabled() { + QueueInfoProtoOrBuilder p = viaProto ? proto : builder; + return (p.hasIntraQueuePreemptionDisabled()) ? p + .getIntraQueuePreemptionDisabled() : null; + } + + @Override + public void setIntraQueuePreemptionDisabled( + boolean intraQueuePreemptionDisabled) { + maybeInitBuilder(); + builder.setIntraQueuePreemptionDisabled(intraQueuePreemptionDisabled); + } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/api/TestPBImplRecords.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/api/TestPBImplRecords.java index f637ad60e6c..d374415ee5b 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/api/TestPBImplRecords.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/api/TestPBImplRecords.java @@ -500,7 +500,7 @@ public static void setup() throws Exception { // it is recursive(has sub queues) typeValueCache.put(QueueInfo.class, QueueInfo.newInstance("root", 1.0f, 1.0f, 0.1f, null, null, QueueState.RUNNING, ImmutableSet.of("x", "y"), - "x && y", null, false)); + "x && y", null, false, false)); generateByNewInstance(QueueStatistics.class); generateByNewInstance(QueueUserACLInfo.class); generateByNewInstance(YarnClusterMetrics.class); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/monitor/capacity/IntraQueueCandidatesSelector.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/monitor/capacity/IntraQueueCandidatesSelector.java index 32f4c255b15..af9f08a9cc2 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/monitor/capacity/IntraQueueCandidatesSelector.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/monitor/capacity/IntraQueueCandidatesSelector.java @@ -114,8 +114,8 @@ public int compare(TempAppPerPartition ta1, TempAppPerPartition ta2) { continue; } - // Don't preempt if disabled for this queue. - if (leafQueue.getPreemptionDisabled()) { + // Don't preempt if intra-queue preemption is disabled for this queue. + if (leafQueue.getIntraQueuePreemptionDisabled()) { continue; } 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 3f3cbd217d9..9fb2323ff2e 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 @@ -78,6 +78,9 @@ new HashMap(); volatile boolean reservationsContinueLooking; private boolean preemptionDisabled; + // Indicates if the in-queue preemption setting is ever disabled within the + // hierarchy of this queue. + private boolean intraQueuePreemptionDisabledInHierarchy; // Track resource usage-by-label like used-resource/pending-resource, etc. volatile ResourceUsage queueUsage; @@ -303,6 +306,9 @@ synchronized void setupQueueConfigs(Resource clusterResource) .getReservationContinueLook(); this.preemptionDisabled = isQueueHierarchyPreemptionDisabled(this); + this.intraQueuePreemptionDisabledInHierarchy = + isIntraQueueHierarchyPreemptionDisabled(this); + this.userWeights = getUserWeightsFromHierarchy(); } @@ -332,6 +338,8 @@ protected QueueInfo getQueueInfo() { queueInfo.setCurrentCapacity(getUsedCapacity()); queueInfo.setQueueStatistics(getQueueStatistics()); queueInfo.setPreemptionDisabled(preemptionDisabled); + queueInfo.setIntraQueuePreemptionDisabled( + getIntraQueuePreemptionDisabled()); return queueInfo; } @@ -406,6 +414,16 @@ public boolean getReservationContinueLooking() { public boolean getPreemptionDisabled() { return preemptionDisabled; } + + @Private + public boolean getIntraQueuePreemptionDisabled() { + return intraQueuePreemptionDisabledInHierarchy || preemptionDisabled; + } + + @Private + public boolean getIntraQueuePreemptionDisabledInHierarchy() { + return intraQueuePreemptionDisabledInHierarchy; + } @Private public QueueCapacities getQueueCapacities() { @@ -418,12 +436,13 @@ public ResourceUsage getQueueResourceUsage() { } /** - * The specified queue is preemptable if system-wide preemption is turned on - * unless any queue in the qPath hierarchy has explicitly turned - * preemption off. - * NOTE: Preemptability is inherited from a queue's parent. - * - * @return true if queue has preemption disabled, false otherwise + * The specified queue is cross-queue preemptable if system-wide cross-queue + * preemption is turned on unless any queue in the qPath hierarchy + * has explicitly turned cross-queue preemption off. + * NOTE: Cross-queue preemptability is inherited from a queue's parent. + * + * @param q queue to check preemption state + * @return true if queue has cross-queue preemption disabled, false otherwise */ private boolean isQueueHierarchyPreemptionDisabled(CSQueue q) { CapacitySchedulerConfiguration csConf = csContext.getConfiguration(); @@ -450,7 +469,42 @@ private boolean isQueueHierarchyPreemptionDisabled(CSQueue q) { return csConf.getPreemptionDisabled(q.getQueuePath(), parentQ.getPreemptionDisabled()); } - + + /** + * The specified queue is intra-queue preemptable if + * 1) system-wide intra-queue preemption is turned on + * 2) no queue in the qPath hierarchy has explicitly turned off intra + * queue preemption. + * NOTE: Intra-queue preemptability is inherited from a queue's parent. + * + * @param q queue to check intra-queue preemption state + * @return true if queue has intra-queue preemption disabled, false otherwise + */ + private boolean isIntraQueueHierarchyPreemptionDisabled(CSQueue q) { + CapacitySchedulerConfiguration csConf = csContext.getConfiguration(); + boolean systemWideIntraQueuePreemption = + csConf.getBoolean( + CapacitySchedulerConfiguration.INTRAQUEUE_PREEMPTION_ENABLED, + CapacitySchedulerConfiguration + .DEFAULT_INTRAQUEUE_PREEMPTION_ENABLED); + // Intra-queue preemption is disabled for this queue if the system-wide + // intra-queue preemption flag is false + if (!systemWideIntraQueuePreemption) return true; + + // Check if this is the root queue and the root queue's intra-queue + // preemption disable switch is set + CSQueue parentQ = q.getParent(); + if (parentQ == null) { + return csConf.getIntraQueuePreemptionDisabled(q.getQueuePath(), false); + } + + // At this point, the master preemption switch is enabled down to this + // queue's level. Determine whether or not intra-queue preemption is enabled + // down to this queu's level and return that value. + return csConf.getIntraQueuePreemptionDisabled(q.getQueuePath(), + parentQ.getIntraQueuePreemptionDisabledInHierarchy()); + } + private Resource getCurrentLimitResource(String nodePartition, Resource clusterResource, ResourceLimits currentResourceLimits, SchedulingMode schedulingMode) { 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/CSQueue.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/CSQueue.java index 2c003aa45e2..ff02e61249e 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/CSQueue.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/CSQueue.java @@ -289,7 +289,21 @@ public void attachContainer(Resource clusterResource, * @return true if disable_preemption is set, false if not */ public boolean getPreemptionDisabled(); - + + /** + * Check whether intra-queue preemption is disabled for this queue + * @return true if either intra-queue preemption or inter-queue preemption + * is disabled for this queue, false if neither is disabled. + */ + public boolean getIntraQueuePreemptionDisabled(); + + /** + * Determines whether or not the intra-queue preemption disabled switch is set + * at any level in this queue's hierarchy. + * @return state of the intra-queue preemption switch at this queue level + */ + public boolean getIntraQueuePreemptionDisabledInHierarchy(); + /** * Get QueueCapacities of this queue * @return queueCapacities 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/CapacitySchedulerConfiguration.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/CapacitySchedulerConfiguration.java index a32cb046c7d..db4a2d40024 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/CapacitySchedulerConfiguration.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/CapacitySchedulerConfiguration.java @@ -998,6 +998,21 @@ public boolean getPreemptionDisabled(String queue, boolean defaultVal) { return preemptionDisabled; } + /** + * Indicates whether intra-queue preemption is disabled on the specified queue + * + * @param queue queue path to query + * @param defaultVal used as default if the property is not set in the + * configuration + * @return true if preemption is disabled on queue, false otherwise + */ + public boolean getIntraQueuePreemptionDisabled(String queue, + boolean defaultVal) { + return + getBoolean(getQueuePrefix(queue) + INTRA_QUEUE_PREEMPTION_CONFIG_PREFIX + + QUEUE_PREEMPTION_DISABLED, defaultVal); + } + /** * Get configured node labels in a given queuePath */ diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/CapacitySchedulerPage.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/CapacitySchedulerPage.java index 5c840d8a987..47e1fd98238 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/CapacitySchedulerPage.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/CapacitySchedulerPage.java @@ -183,6 +183,8 @@ private void renderCommonLeafQueueInfo(ResponseInfo ri) { _("Accessible Node Labels:", StringUtils.join(",", lqinfo.getNodeLabels())). _("Ordering Policy: ", lqinfo.getOrderingPolicyInfo()). _("Preemption:", lqinfo.getPreemptionDisabled() ? "disabled" : "enabled"). + _("Intra-queue Preemption:", lqinfo.getIntraQueuePreemptionDisabled() + ? "disabled" : "enabled"). _("Default Node Label Expression:", lqinfo.getDefaultNodeLabelExpression() == null ? NodeLabel.DEFAULT_NODE_LABEL_PARTITION diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/CapacitySchedulerLeafQueueInfo.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/CapacitySchedulerLeafQueueInfo.java index e0ac56fb889..4657e9b7eec 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/CapacitySchedulerLeafQueueInfo.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/CapacitySchedulerLeafQueueInfo.java @@ -46,6 +46,7 @@ protected ResourceInfo usedAMResource; protected ResourceInfo userAMResourceLimit; protected boolean preemptionDisabled; + protected boolean intraQueuePreemptionDisabled; protected String defaultNodeLabelExpression; protected int defaultPriority; @@ -68,6 +69,7 @@ AMResourceLimit = new ResourceInfo(q.getAMResourceLimit()); usedAMResource = new ResourceInfo(q.getQueueResourceUsage().getAMUsed()); preemptionDisabled = q.getPreemptionDisabled(); + intraQueuePreemptionDisabled = q.getIntraQueuePreemptionDisabled(); orderingPolicyInfo = q.getOrderingPolicy().getInfo(); defaultNodeLabelExpression = q.getDefaultNodeLabelExpression(); defaultPriority = q.getDefaultApplicationPriority().getPriority(); @@ -141,6 +143,10 @@ public ResourceInfo getUserAMResourceLimit() { public boolean getPreemptionDisabled() { return preemptionDisabled; } + + public boolean getIntraQueuePreemptionDisabled() { + return intraQueuePreemptionDisabled; + } public String getOrderingPolicyInfo() { return orderingPolicyInfo; 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/TestSchedulerApplicationAttempt.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/TestSchedulerApplicationAttempt.java index 4848441b25b..ee8a997c6bc 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/TestSchedulerApplicationAttempt.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/TestSchedulerApplicationAttempt.java @@ -162,7 +162,7 @@ private Queue createQueue(String name, Queue parent) { private Queue createQueue(String name, Queue parent, float capacity) { QueueMetrics metrics = QueueMetrics.forQueue(name, parent, false, conf); QueueInfo queueInfo = QueueInfo.newInstance(name, capacity, 1.0f, 0, null, - null, QueueState.RUNNING, null, "", null, false); + null, QueueState.RUNNING, null, "", null, false, false); ActiveUsersManager activeUsersManager = new ActiveUsersManager(metrics); Queue queue = mock(Queue.class); when(queue.getMetrics()).thenReturn(metrics); 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 23fb29d9e19..3e8e51e7137 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 @@ -3364,7 +3364,7 @@ private AbstractCSQueue createQueue(String name, Queue parent, float capacity, float absCap) { CSQueueMetrics metrics = CSQueueMetrics.forQueue(name, parent, false, cs.getConf()); QueueInfo queueInfo = QueueInfo.newInstance(name, capacity, 1.0f, 0, null, - null, QueueState.RUNNING, null, "", null, false); + null, QueueState.RUNNING, null, "", null, false, false); ActiveUsersManager activeUsersManager = new ActiveUsersManager(metrics); AbstractCSQueue queue = mock(AbstractCSQueue.class); when(queue.getMetrics()).thenReturn(metrics); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesCapacitySched.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesCapacitySched.java index 9379367740c..421d7ef7ca7 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesCapacitySched.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesCapacitySched.java @@ -353,7 +353,7 @@ private void verifySubQueue(JSONObject info, String q, int numExpectedElements = 18; boolean isParentQueue = true; if (!info.has("queues")) { - numExpectedElements = 31; + numExpectedElements = 32; isParentQueue = false; } assertEquals("incorrect number of elements", numExpectedElements, info.length()); 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 9be6652200a..1e7b88691b9 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 @@ -230,6 +230,7 @@ The following configuration parameters can be configured in yarn-site.xml to con | Property | Description | |:---- |:---- | | `yarn.scheduler.capacity..disable_preemption` | This configuration can be set to `true` to selectively disable preemption of application containers submitted to a given queue. This property applies only when system wide preemption is enabled by configuring `yarn.resourcemanager.scheduler.monitor.enable` to *true* and `yarn.resourcemanager.scheduler.monitor.policies` to *ProportionalCapacityPreemptionPolicy*. If this property is not set for a queue, then the property value is inherited from the queue's parent. Default value is false. +| `yarn.scheduler.capacity..intra-queue-preemption.disable_preemption` | This configuration can be set to *true* to selectively disable intra-queue preemption of application containers submitted to a given queue. This property applies only when system wide preemption is enabled by configuring `yarn.resourcemanager.scheduler.monitor.enable` to *true*, `yarn.resourcemanager.scheduler.monitor.policies` to *ProportionalCapacityPreemptionPolicy*, and `yarn.resourcemanager.monitor.capacity.preemption.intra-queue-preemption.enabled` to *true*. If this property is not set for a queue, then the property value is inherited from the queue's parent. Default value is *false*. ###Reservation Properties