diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java index 6a14c4c..d52dbbb 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java @@ -64,6 +64,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptEvent; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptEventType; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptImpl; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptState; import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainer; import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainerEventType; @@ -954,6 +955,15 @@ public Allocation allocate(ApplicationAttemptId appAttemptId, getClusterResource(), minimumAllocation, getMaximumResourceCapability(), incrAllocation); + // Check if AM take all VCores + for (ResourceRequest req : ask) { + if (req.getPriority().equals(RMAppAttemptImpl.AM_CONTAINER_PRIORITY) && + req.getCapability().getVirtualCores() >= + rootMetrics.getAvailableVirtualCores()) { + return EMPTY_ALLOCATION; + } + } + // Record container allocation start time application.recordContainerRequestTime(getClock().getTime()); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairScheduler.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairScheduler.java index a75b5ce..78e89a4 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairScheduler.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairScheduler.java @@ -92,6 +92,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode; import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeResourceUpdateEvent; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.AbstractYarnScheduler; +import org.apache.hadoop.yarn.server.resourcemanager.scheduler.Allocation; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.QueueMetrics; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerApplicationAttempt; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerNode; @@ -3379,6 +3380,50 @@ public void testQueueMaxAMShareDefault() throws Exception { 0, queue2.getAmResourceUsage().getMemory()); } + @Test + public void testAMTakeAllVCores() throws Exception { + // Set the maximum allocation vcores no less than 4, + // so that after normalization, the resource request will be more than 4. + conf.setInt(YarnConfiguration.RM_SCHEDULER_MAXIMUM_ALLOCATION_VCORES, 6); + scheduler.init(conf); + scheduler.start(); + scheduler.reinitialize(conf, resourceManager.getRMContext()); + + RMNode node = + MockNodes.newNodeInfo(1, Resources.createResource(8192, 4), + 0, "127.0.0.1"); + NodeAddedSchedulerEvent nodeEvent = new NodeAddedSchedulerEvent(node); + scheduler.handle(nodeEvent); + scheduler.update(); + + Resource amResource1 = Resource.newInstance(1024, 1); + int amPriority = RMAppAttemptImpl.AM_CONTAINER_PRIORITY.getPriority(); + + ApplicationAttemptId attId = createAppAttemptId(1, 1); + createApplicationWithAMResource(attId, "queue1", "test1", amResource1); + ResourceRequest request = createResourceRequest(1024, 2, + ResourceRequest.ANY, amPriority, 1, true); + List ask = new ArrayList<>(); + ask.add(request); + + Allocation alloc = scheduler.allocate(attId, ask, + new ArrayList(), null, null, null, null); + + assertNotEquals(null, alloc.getNMTokens()); + + ApplicationAttemptId attId2 = createAppAttemptId(2, 1); + createApplicationWithAMResource(attId2, "queue1", "test1", amResource1); + ResourceRequest request2 = createResourceRequest(1024, 10, + ResourceRequest.ANY, amPriority, 1, true); + List ask2 = new ArrayList<>(); + ask2.add(request2); + + Allocation alloc2 = scheduler.allocate(attId2, ask2, + new ArrayList(), null, null, null, null); + + assertEquals(null, alloc2.getNMTokens()); + } + /** * The test verifies container gets reserved when not over maxAMShare, * reserved container gets unreserved when over maxAMShare,