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/FSLeafQueue.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSLeafQueue.java index 3b3f6ce..b7659bc 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSLeafQueue.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSLeafQueue.java @@ -138,6 +138,11 @@ public void recomputeShares() { } @Override + public void recomputeStaticShares() { + policy.computeStaticShares(getRunnableAppSchedulables(), getStaticFairShare()); + } + + @Override public Resource getDemand() { return demand; } 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/FSParentQueue.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSParentQueue.java index 9af72a5..36ca014 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSParentQueue.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSParentQueue.java @@ -35,7 +35,6 @@ import org.apache.hadoop.yarn.api.records.Resource; import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainer; import org.apache.hadoop.yarn.util.resource.Resources; -import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainer; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ActiveUsersManager; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerApplicationAttempt; @@ -69,6 +68,15 @@ public void recomputeShares() { } @Override + public void recomputeStaticShares() { + policy.computeStaticShares(childQueues, getStaticFairShare()); + for (FSQueue childQueue : childQueues) { + childQueue.getMetrics().setStaticFairShare(childQueue.getStaticFairShare()); + childQueue.recomputeStaticShares(); + } + } + + @Override public Resource getDemand() { return demand; } 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/FSQueue.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSQueue.java index 1e94046..70629f9 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSQueue.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSQueue.java @@ -145,6 +145,12 @@ public void setFairShare(Resource fairShare) { super.setFairShare(fairShare); metrics.setFairShare(fairShare); } + + @Override + public void setStaticFairShare(Resource staticFairShare) { + super.setStaticFairShare(staticFairShare); + metrics.setStaticFairShare(staticFairShare); + } public boolean hasAccess(QueueACL acl, UserGroupInformation user) { return scheduler.getAllocationConfiguration().hasAccess(name, acl, user); @@ -155,7 +161,13 @@ public boolean hasAccess(QueueACL acl, UserGroupInformation user) { * queue's current share */ public abstract void recomputeShares(); - + + /** + * Recomputes the static shares of all child queues and applications based on + * this queue's current share + */ + public abstract void recomputeStaticShares(); + /** * Gets the children of this queue, if any. */ 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/FSQueueMetrics.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSQueueMetrics.java index ff0956e..d14ad1d 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSQueueMetrics.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSQueueMetrics.java @@ -33,6 +33,8 @@ @Metric("Fair share of memory in MB") MutableGaugeInt fairShareMB; @Metric("Fair share of CPU in vcores") MutableGaugeInt fairShareVCores; + @Metric("Static fair share of memory in MB") MutableGaugeInt staticFairShareMB; + @Metric("Static fair share of CPU in vcores") MutableGaugeInt staticFairShareVCores; @Metric("Minimum share of memory in MB") MutableGaugeInt minShareMB; @Metric("Minimum share of CPU in vcores") MutableGaugeInt minShareVCores; @Metric("Maximum share of memory in MB") MutableGaugeInt maxShareMB; @@ -55,7 +57,20 @@ public int getFairShareMB() { public int getFairShareVirtualCores() { return fairShareVCores.value(); } - + + public void setStaticFairShare(Resource resource) { + staticFairShareMB.set(resource.getMemory()); + staticFairShareVCores.set(resource.getVirtualCores()); + } + + public int getStaticFairShareMB() { + return staticFairShareMB.value(); + } + + public int getStaticFairShareVCores() { + return staticFairShareVCores.value(); + } + public void setMinShare(Resource resource) { minShareMB.set(resource.getMemory()); minShareVCores.set(resource.getVirtualCores()); 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 8765ba0..51e9bb8 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 @@ -853,6 +853,8 @@ private synchronized void addNode(RMNode node) { Resources.addTo(clusterResource, node.getTotalCapability()); updateRootQueueMetrics(); + queueMgr.getRootQueue().setStaticFairShare(clusterResource); + queueMgr.getRootQueue().recomputeStaticShares(); LOG.info("Added node " + node.getNodeAddress() + " cluster capacity: " + clusterResource); } @@ -887,6 +889,8 @@ private synchronized void removeNode(RMNode rmNode) { } nodes.remove(rmNode.getNodeID()); + queueMgr.getRootQueue().setStaticFairShare(clusterResource); + queueMgr.getRootQueue().recomputeStaticShares(); LOG.info("Removed node " + rmNode.getNodeAddress() + " cluster capacity: " + clusterResource); } @@ -1413,6 +1417,8 @@ public void onReload(AllocationConfiguration queueInfo) { allocConf = queueInfo; allocConf.getDefaultSchedulingPolicy().initialize(clusterResource); queueMgr.updateAllocationConfiguration(allocConf); + queueMgr.getRootQueue().setStaticFairShare(clusterResource); + queueMgr.getRootQueue().recomputeStaticShares(); } } } 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/Schedulable.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/Schedulable.java index 5134be4..3b9d7db 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/Schedulable.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/Schedulable.java @@ -60,6 +60,8 @@ public abstract class Schedulable { /** Fair share assigned to this Schedulable */ private Resource fairShare = Resources.createResource(0); + /** Guaranteed fair share assigned to this Schedulable */ + private Resource staticFairShare = Resources.createResource(0); /** * Name of job/queue, used for debugging as well as for breaking ties in @@ -116,6 +118,16 @@ public Resource getFairShare() { return fairShare; } + /** Assign a guaranteed fair share to this Schedulable. */ + public void setStaticFairShare(Resource staticFairShare) { + this.staticFairShare = staticFairShare; + } + + /** Get the guaranteed fair share assigned to this Schedulable. */ + public Resource getStaticFairShare() { + return staticFairShare; + } + /** * Returns true if queue has atleast one app running. Always returns true for * AppSchedulables. 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/SchedulingPolicy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/SchedulingPolicy.java index 1087c73..12ce47d 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/SchedulingPolicy.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/SchedulingPolicy.java @@ -141,6 +141,16 @@ public abstract void computeShares( Collection schedulables, Resource totalResources); /** + * Computes and updates the static shares of {@link Schedulable}s as per the + * {@link SchedulingPolicy}. + * + * @param schedulables {@link Schedulable}s whose shares are to be updated + * @param totalResources Total {@link Resource}s in the cluster + */ + public abstract void computeStaticShares( + Collection schedulables, Resource totalResources); + + /** * Check if the resource usage is over the fair share under this policy * * @param usage {@link Resource} the resource usage 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/policies/ComputeFairShares.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/ComputeFairShares.java index 6363ec0..9fa8626 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/ComputeFairShares.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/ComputeFairShares.java @@ -56,7 +56,21 @@ public static void computeShares( } } - computeSharesInternal(activeSchedulables, totalResources, type); + computeSharesInternal(activeSchedulables, totalResources, type, false); + } + + /** + * Compute the static fair share of the given schedulables. The static fair + * share is an allocation of shares considering all schedulables, i.e., + * active and inactive. + * @param schedulables + * @param totalResources + * @param type + */ + public static void computeStaticShares( + Collection schedulables, Resource totalResources, + ResourceType type) { + computeSharesInternal(schedulables, totalResources, type, true); } /** @@ -102,7 +116,7 @@ public static void computeShares( */ private static void computeSharesInternal( Collection schedulables, Resource totalResources, - ResourceType type) { + ResourceType type, boolean isStaticShare) { if (schedulables.isEmpty()) { return; } @@ -145,7 +159,13 @@ private static void computeSharesInternal( } // Set the fair shares based on the value of R we've converged to for (Schedulable sched : schedulables) { - setResourceValue(computeShare(sched, right, type), sched.getFairShare(), type); + if (isStaticShare) { + setResourceValue( + computeShare(sched, right, type), sched.getStaticFairShare(), type); + } else { + setResourceValue( + computeShare(sched, right, type), sched.getFairShare(), type); + } } } 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/policies/DominantResourceFairnessPolicy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/DominantResourceFairnessPolicy.java index af674b9..850a73e 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/DominantResourceFairnessPolicy.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/DominantResourceFairnessPolicy.java @@ -68,6 +68,14 @@ public void computeShares(Collection schedulables, ComputeFairShares.computeShares(schedulables, totalResources, type); } } + + @Override + public void computeStaticShares(Collection schedulables, + Resource totalResources) { + for (ResourceType type : ResourceType.values()) { + ComputeFairShares.computeStaticShares(schedulables, totalResources, type); + } + } @Override public boolean checkIfUsageOverFairShare(Resource usage, Resource fairShare) { 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/policies/FairSharePolicy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FairSharePolicy.java index c51852f..0e6a5d0 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FairSharePolicy.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FairSharePolicy.java @@ -120,6 +120,13 @@ public void computeShares(Collection schedulables, } @Override + public void computeStaticShares(Collection schedulables, + Resource totalResources) { + ComputeFairShares.computeStaticShares(schedulables, totalResources, + ResourceType.MEMORY); + } + + @Override public boolean checkIfUsageOverFairShare(Resource usage, Resource fairShare) { return Resources.greaterThan(RESOURCE_CALCULATOR, null, usage, fairShare); } 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/policies/FifoPolicy.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FifoPolicy.java index 0f43097..4efc13d 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FifoPolicy.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/policies/FifoPolicy.java @@ -88,6 +88,23 @@ public void computeShares(Collection schedulables, } @Override + public void computeStaticShares(Collection schedulables, + Resource totalResources) { + if (schedulables.isEmpty()) { + return; + } + + Schedulable earliest = null; + for (Schedulable schedulable : schedulables) { + if (earliest == null || + schedulable.getStartTime() < earliest.getStartTime()) { + earliest = schedulable; + } + } + earliest.setStaticFairShare(Resources.clone(totalResources)); + } + + @Override public boolean checkIfUsageOverFairShare(Resource usage, Resource fairShare) { throw new UnsupportedOperationException( "FifoPolicy doesn't support checkIfUsageOverFairshare operation, " + 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/TestComputeFairShares.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestComputeFairShares.java index 9d8dd07..8c3c7d8 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestComputeFairShares.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestComputeFairShares.java @@ -54,6 +54,9 @@ public void testEqualSharing() { ComputeFairShares.computeShares(scheds, Resources.createResource(40), ResourceType.MEMORY); verifyMemoryShares(10, 10, 10, 10); + ComputeFairShares.computeStaticShares(scheds, + Resources.createResource(40), ResourceType.MEMORY); + verifyMemoryStaticShares(10, 10, 10, 10); } /** @@ -72,6 +75,9 @@ public void testLowMaxShares() { ComputeFairShares.computeShares(scheds, Resources.createResource(40), ResourceType.MEMORY); verifyMemoryShares(13, 13, 11, 3); + ComputeFairShares.computeStaticShares(scheds, + Resources.createResource(40), ResourceType.MEMORY); + verifyMemoryStaticShares(13, 13, 11, 3); } @@ -92,6 +98,9 @@ public void testMinShares() { ComputeFairShares.computeShares(scheds, Resources.createResource(40), ResourceType.MEMORY); verifyMemoryShares(20, 18, 0, 2); + ComputeFairShares.computeStaticShares(scheds, + Resources.createResource(40), ResourceType.MEMORY); + verifyMemoryStaticShares(20, 18, 0, 2); } /** @@ -107,6 +116,9 @@ public void testWeightedSharing() { ComputeFairShares.computeShares(scheds, Resources.createResource(45), ResourceType.MEMORY); verifyMemoryShares(20, 10, 10, 5); + ComputeFairShares.computeStaticShares(scheds, + Resources.createResource(45), ResourceType.MEMORY); + verifyMemoryStaticShares(20, 10, 10, 5); } /** @@ -125,9 +137,11 @@ public void testWeightedSharingWithMaxShares() { ComputeFairShares.computeShares(scheds, Resources.createResource(45), ResourceType.MEMORY); verifyMemoryShares(10, 11, 16, 8); + ComputeFairShares.computeStaticShares(scheds, + Resources.createResource(45), ResourceType.MEMORY); + verifyMemoryStaticShares(10, 11, 16, 8); } - /** * Weighted fair sharing test with min shares. As in the min share test above, * pool 1 has a min share greater than its demand so it only gets its demand. @@ -144,6 +158,9 @@ public void testWeightedSharingWithMinShares() { ComputeFairShares.computeShares(scheds, Resources.createResource(45), ResourceType.MEMORY); verifyMemoryShares(20, 5, 5, 15); + ComputeFairShares.computeStaticShares(scheds, + Resources.createResource(45), ResourceType.MEMORY); + verifyMemoryStaticShares(20, 5, 5, 15); } /** @@ -160,6 +177,10 @@ public void testLargeShares() { ComputeFairShares.computeShares(scheds, Resources.createResource(40 * million), ResourceType.MEMORY); verifyMemoryShares(10 * million, 10 * million, 10 * million, 10 * million); + ComputeFairShares.computeStaticShares(scheds, + Resources.createResource(40 * million), ResourceType.MEMORY); + verifyMemoryStaticShares(10 * million, 10 * million, 10 * million, + 10 * million); } /** @@ -170,6 +191,9 @@ public void testEmptyList() { ComputeFairShares.computeShares(scheds, Resources.createResource(40), ResourceType.MEMORY); verifyMemoryShares(); + ComputeFairShares.computeStaticShares(scheds, + Resources.createResource(40), ResourceType.MEMORY); + verifyMemoryStaticShares(); } /** @@ -188,6 +212,9 @@ public void testCPU() { ComputeFairShares.computeShares(scheds, Resources.createResource(0, 45), ResourceType.CPU); verifyCPUShares(20, 5, 5, 15); + ComputeFairShares.computeStaticShares(scheds, + Resources.createResource(0, 45), ResourceType.CPU); + verifyCPUStaticShares(20, 5, 5, 15); } /** @@ -199,6 +226,17 @@ private void verifyMemoryShares(int... shares) { Assert.assertEquals(shares[i], scheds.get(i).getFairShare().getMemory()); } } + + /** + * Check that a given list of static shares have been assigned to this.scheds. + */ + private void verifyMemoryStaticShares(int... shares) { + Assert.assertEquals(scheds.size(), shares.length); + for (int i = 0; i < shares.length; i++) { + Assert.assertEquals(shares[i], + scheds.get(i).getStaticFairShare().getMemory()); + } + } /** * Check that a given list of shares have been assigned to this.scheds. @@ -209,4 +247,15 @@ private void verifyCPUShares(int... shares) { Assert.assertEquals(shares[i], scheds.get(i).getFairShare().getVirtualCores()); } } + + /** + * Check that a given list of static shares have been assigned to this.scheds. + */ + private void verifyCPUStaticShares(int... shares) { + Assert.assertEquals(scheds.size(), shares.length); + for (int i = 0; i < shares.length; i++) { + Assert.assertEquals(shares[i], + scheds.get(i).getStaticFairShare().getVirtualCores()); + } + } } 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 0ada021..349172a 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 @@ -295,14 +295,19 @@ public void testSimpleFairShareCalculation() throws IOException { createSchedulingRequest(10 * 1024, "root.default", "user1"); scheduler.update(); + scheduler.getQueueManager().getRootQueue() + .setStaticFairShare(scheduler.getClusterResource()); + scheduler.getQueueManager().getRootQueue().recomputeStaticShares(); Collection queues = scheduler.getQueueManager().getLeafQueues(); assertEquals(3, queues.size()); - // Divided three ways - betwen the two queues and the default queue + // Divided three ways - between the two queues and the default queue for (FSLeafQueue p : queues) { assertEquals(3414, p.getFairShare().getMemory()); assertEquals(3414, p.getMetrics().getFairShareMB()); + assertEquals(3414, p.getStaticFairShare().getMemory()); + assertEquals(3414, p.getMetrics().getStaticFairShareMB()); } } @@ -326,6 +331,9 @@ public void testSimpleHierarchicalFairShareCalculation() throws IOException { createSchedulingRequest(10 * 1024, "root.default", "user1"); scheduler.update(); + scheduler.getQueueManager().getRootQueue() + .setStaticFairShare(scheduler.getClusterResource()); + scheduler.getQueueManager().getRootQueue().recomputeStaticShares(); QueueManager queueManager = scheduler.getQueueManager(); Collection queues = queueManager.getLeafQueues(); @@ -336,10 +344,16 @@ public void testSimpleHierarchicalFairShareCalculation() throws IOException { FSLeafQueue queue3 = queueManager.getLeafQueue("parent.queue3", true); assertEquals(capacity / 2, queue1.getFairShare().getMemory()); assertEquals(capacity / 2, queue1.getMetrics().getFairShareMB()); + assertEquals(capacity / 2, queue1.getStaticFairShare().getMemory()); + assertEquals(capacity / 2, queue1.getMetrics().getStaticFairShareMB()); assertEquals(capacity / 4, queue2.getFairShare().getMemory()); assertEquals(capacity / 4, queue2.getMetrics().getFairShareMB()); + assertEquals(capacity / 4, queue2.getStaticFairShare().getMemory()); + assertEquals(capacity / 4, queue2.getMetrics().getStaticFairShareMB()); assertEquals(capacity / 4, queue3.getFairShare().getMemory()); assertEquals(capacity / 4, queue3.getMetrics().getFairShareMB()); + assertEquals(capacity / 4, queue3.getStaticFairShare().getMemory()); + assertEquals(capacity / 4, queue3.getMetrics().getStaticFairShareMB()); } @Test @@ -774,6 +788,9 @@ public void testFairShareAndWeightsInNestedUserQueueRule() throws Exception { createSchedulingRequest(10 * 1024, "root.default", "user3"); scheduler.update(); + scheduler.getQueueManager().getRootQueue() + .setStaticFairShare(scheduler.getClusterResource()); + scheduler.getQueueManager().getRootQueue().recomputeStaticShares(); Collection leafQueues = scheduler.getQueueManager() .getLeafQueues(); @@ -783,12 +800,98 @@ public void testFairShareAndWeightsInNestedUserQueueRule() throws Exception { || leaf.getName().equals("root.parentq.user2")) { // assert that the fair share is 1/4th node1's capacity assertEquals(capacity / 4, leaf.getFairShare().getMemory()); + // assert that the static fair share is 1/4th node1's capacity + assertEquals(capacity / 4, leaf.getStaticFairShare().getMemory()); // assert weights are equal for both the user queues assertEquals(1.0, leaf.getWeights().getWeight(ResourceType.MEMORY), 0); } } } - + + @Test + public void testStaticFairShareWithReloadAndNodeAddRemove() throws Exception { + conf.set(FairSchedulerConfiguration.ALLOCATION_FILE, ALLOC_FILE); + + PrintWriter out = new PrintWriter(new FileWriter(ALLOC_FILE)); + out.println(""); + out.println(""); + out.println("fair"); + out.println(""); + out.println(" drf"); + out.println(" "); + out.println(" 1"); + out.println(" "); + out.println(" "); + out.println(" 1"); + out.println(" "); + out.println(""); + out.println(""); + out.close(); + + scheduler.init(conf); + scheduler.start(); + scheduler.reinitialize(conf, resourceManager.getRMContext()); + + // The static fair share for all queues should be 0 + QueueManager queueManager = scheduler.getQueueManager(); + assertEquals(0, queueManager.getLeafQueue("child1", false) + .getStaticFairShare().getMemory()); + assertEquals(0, queueManager.getLeafQueue("child2", false) + .getStaticFairShare().getMemory()); + + // Add one node + RMNode node1 = + MockNodes + .newNodeInfo(1, Resources.createResource(6144), 1, "127.0.0.1"); + NodeAddedSchedulerEvent nodeEvent1 = new NodeAddedSchedulerEvent(node1); + scheduler.handle(nodeEvent1); + assertEquals(6144, scheduler.getClusterResource().getMemory()); + + // The static fair shares for all queues should be updated + assertEquals(2048, queueManager.getLeafQueue("child1", false) + .getStaticFairShare().getMemory()); + assertEquals(2048, queueManager.getLeafQueue("child2", false) + .getStaticFairShare().getMemory()); + + // Reload the allocation configuration file + out = new PrintWriter(new FileWriter(ALLOC_FILE)); + out.println(""); + out.println(""); + out.println("fair"); + out.println(""); + out.println(" drf"); + out.println(" "); + out.println(" 1"); + out.println(" "); + out.println(" "); + out.println(" 2"); + out.println(" "); + out.println(" "); + out.println(" 2"); + out.println(" "); + out.println(""); + out.println(""); + out.close(); + scheduler.reinitialize(conf, resourceManager.getRMContext()); + + // The static fair shares for all queues should be updated + assertEquals(1024, queueManager.getLeafQueue("child1", false) + .getStaticFairShare().getMemory()); + assertEquals(2048, queueManager.getLeafQueue("child2", false) + .getStaticFairShare().getMemory()); + assertEquals(2048, queueManager.getLeafQueue("child3", false) + .getStaticFairShare().getMemory()); + + // Remove the node, static fair shares should back to 0 + NodeRemovedSchedulerEvent nodeEvent2 = new NodeRemovedSchedulerEvent(node1); + scheduler.handle(nodeEvent2); + assertEquals(0, scheduler.getClusterResource().getMemory()); + assertEquals(0, queueManager.getLeafQueue("child1", false) + .getStaticFairShare().getMemory()); + assertEquals(0, queueManager.getLeafQueue("child2", false) + .getStaticFairShare().getMemory()); + } + /** * Make allocation requests and ensure they are reflected in queue demand. */ @@ -876,7 +979,7 @@ public void testAppAdditionAndRemoval() throws Exception { } @Test - public void testHierarchicalQueueAllocationFileParsing() throws IOException, SAXException, + public void testHierarchicalQueueAllocationFileParsing() throws IOException, SAXException, AllocationConfigurationException, ParserConfigurationException { conf.set(FairSchedulerConfiguration.ALLOCATION_FILE, ALLOC_FILE); 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/TestFairSchedulerFairShare.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairSchedulerFairShare.java index 8b8ce93..7bf2c55 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairSchedulerFairShare.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairSchedulerFairShare.java @@ -109,13 +109,15 @@ public void testFairShareNoAppsRunning() throws IOException { for (FSLeafQueue leaf : leafQueues) { if (leaf.getName().startsWith("root.parentA")) { - assertEquals(0, (double) leaf.getFairShare().getMemory() / nodeCapacity - * 100, 0); + assertEquals(0, (double) leaf.getFairShare().getMemory() / nodeCapacity, + 0); } else if (leaf.getName().startsWith("root.parentB")) { - assertEquals(0, (double) leaf.getFairShare().getMemory() / nodeCapacity - * 100, 0.1); + assertEquals(0, (double) leaf.getFairShare().getMemory() / nodeCapacity, + 0); } } + + verifyStaticFairShareMemory(leafQueues, nodeCapacity); } @Test @@ -135,14 +137,15 @@ public void testFairShareOneAppRunning() throws IOException { 100, (double) scheduler.getQueueManager() .getLeafQueue("root.parentA.childA1", false).getFairShare() - .getMemory() - / nodeCapacity * 100, 0.1); + .getMemory() / nodeCapacity * 100, 0.1); assertEquals( 0, (double) scheduler.getQueueManager() .getLeafQueue("root.parentA.childA2", false).getFairShare() - .getMemory() - / nodeCapacity * 100, 0.1); + .getMemory() / nodeCapacity, 0.1); + + verifyStaticFairShareMemory(scheduler.getQueueManager().getLeafQueues(), + nodeCapacity); } @Test @@ -167,6 +170,9 @@ public void testFairShareMultipleActiveQueuesUnderSameParent() .getMemory() / nodeCapacity * 100, .9); } + + verifyStaticFairShareMemory(scheduler.getQueueManager().getLeafQueues(), + nodeCapacity); } @Test @@ -206,6 +212,9 @@ public void testFairShareMultipleActiveQueuesUnderDifferentParent() .getLeafQueue("root.parentB.childB1", false).getFairShare() .getMemory() / nodeCapacity * 100, .9); + + verifyStaticFairShareMemory(scheduler.getQueueManager().getLeafQueues(), + nodeCapacity); } @Test @@ -253,6 +262,9 @@ public void testFairShareResetsToZeroWhenAppsComplete() throws IOException { .getLeafQueue("root.parentA.childA2", false).getFairShare() .getMemory() / nodeCapacity * 100, 0.1); + + verifyStaticFairShareMemory(scheduler.getQueueManager().getLeafQueues(), + nodeCapacity); } @Test @@ -304,5 +316,45 @@ public void testFairShareWithDRFMultipleActiveQueuesUnderDifferentParent() .getLeafQueue("root.parentB.childB1", false).getFairShare() .getVirtualCores() / nodeVCores * 100, .9); + Collection leafQueues = scheduler.getQueueManager() + .getLeafQueues(); + + for (FSLeafQueue leaf : leafQueues) { + if (leaf.getName().startsWith("root.parentA")) { + assertEquals(0.2, + (double) leaf.getStaticFairShare().getMemory() / nodeMem, 0.001); + assertEquals(0.2, + (double) leaf.getStaticFairShare().getVirtualCores() / nodeVCores, + 0.001); + } else if (leaf.getName().startsWith("root.parentB")) { + assertEquals(0.05, + (double) leaf.getStaticFairShare().getMemory() / nodeMem, 0.001); + assertEquals(0.1, + (double) leaf.getStaticFairShare().getVirtualCores() / nodeVCores, + 0.001); + } + } + } + + /** + * Verify whether static fair shares for all leaf queues still follow + * their weight, not related to active/inactive status. + * + * @param leafQueues + * @param nodeCapacity + */ + private void verifyStaticFairShareMemory(Collection leafQueues, + int nodeCapacity) { + for (FSLeafQueue leaf : leafQueues) { + if (leaf.getName().startsWith("root.parentA")) { + assertEquals(0.2, + (double) leaf.getStaticFairShare().getMemory() / nodeCapacity, + 0.001); + } else if (leaf.getName().startsWith("root.parentB")) { + assertEquals(0.05, + (double) leaf.getStaticFairShare().getMemory() / nodeCapacity, + 0.001); + } + } } }