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..1a0b534 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 @@ -34,6 +34,7 @@ public class ComputeFairShares { private static final int COMPUTE_FAIR_SHARES_ITERATIONS = 25; + private static final double EPSILON = 0.000001; /** * Compute fair share of the given schedulables.Fair share is an allocation of @@ -123,8 +124,12 @@ private static void computeSharesInternal( getResourceValue(totalResources, type)); double rMax = 1.0; - while (resourceUsedWithWeightToResourceRatio(rMax, schedulables, type) - < totalResource) { + double currentRU = 0.0; + while ((currentRU = resourceUsedWithWeightToResourceRatio(rMax, + schedulables, type)) < totalResource) { + if (currentRU < EPSILON) { + break; + } rMax *= 2.0; } // Perform the binary search for up to COMPUTE_FAIR_SHARES_ITERATIONS steps @@ -132,7 +137,7 @@ private static void computeSharesInternal( double right = rMax; for (int i = 0; i < COMPUTE_FAIR_SHARES_ITERATIONS; i++) { double mid = (left + right) / 2.0; - int plannedResourceUsed = resourceUsedWithWeightToResourceRatio( + int plannedResourceUsed = (int)resourceUsedWithWeightToResourceRatio( mid, schedulables, type); if (plannedResourceUsed == totalResource) { right = mid; @@ -145,7 +150,8 @@ 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); + setResourceValue((int)computeShare(sched, right, type), + sched.getFairShare(), type); } } @@ -153,12 +159,11 @@ private static void computeSharesInternal( * Compute the resources that would be used given a weight-to-resource ratio * w2rRatio, for use in the computeFairShares algorithm as described in # */ - private static int resourceUsedWithWeightToResourceRatio(double w2rRatio, + private static double resourceUsedWithWeightToResourceRatio(double w2rRatio, Collection schedulables, ResourceType type) { - int resourcesTaken = 0; + double resourcesTaken = 0.0; for (Schedulable sched : schedulables) { - int share = computeShare(sched, w2rRatio, type); - resourcesTaken += share; + resourcesTaken += computeShare(sched, w2rRatio, type); } return resourcesTaken; } @@ -167,12 +172,12 @@ private static int resourceUsedWithWeightToResourceRatio(double w2rRatio, * Compute the resources assigned to a Schedulable given a particular * weight-to-resource ratio w2rRatio. */ - private static int computeShare(Schedulable sched, double w2rRatio, + private static double computeShare(Schedulable sched, double w2rRatio, ResourceType type) { double share = sched.getWeights().getWeight(type) * w2rRatio; share = Math.max(share, getResourceValue(sched.getMinShare(), type)); share = Math.min(share, getResourceValue(sched.getMaxShare(), type)); - return (int) share; + return share; } private static int getResourceValue(Resource resource, ResourceType type) { 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 a7b1738..9fec718 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 @@ -298,11 +298,55 @@ public void testSimpleFairShareCalculation() throws IOException { // Divided three ways - betwen the two queues and the default queue for (FSLeafQueue p : queues) { - assertEquals(3414, p.getFairShare().getMemory()); - assertEquals(3414, p.getMetrics().getFairShareMB()); + assertEquals(3413, p.getFairShare().getMemory()); + assertEquals(3413, p.getMetrics().getFairShareMB()); } } - + + @Test + public void testFairShareWithZeroWeight() throws IOException { + conf.set(FairSchedulerConfiguration.ALLOCATION_FILE, ALLOC_FILE); + // set queueA and queueB weight zero. + PrintWriter out = new PrintWriter(new FileWriter(ALLOC_FILE)); + out.println(""); + out.println(""); + out.println(""); + out.println("0.0"); + out.println(""); + out.println(""); + out.println("0.0"); + out.println(""); + out.println(""); + out.close(); + + scheduler.init(conf); + scheduler.start(); + scheduler.reinitialize(conf, resourceManager.getRMContext()); + + // Add one big node (only care about aggregate capacity) + RMNode node1 = + MockNodes.newNodeInfo(1, Resources.createResource(8 * 1024, 8), 1, + "127.0.0.1"); + NodeAddedSchedulerEvent nodeEvent1 = new NodeAddedSchedulerEvent(node1); + scheduler.handle(nodeEvent1); + + // Queue A wants 2 * 1024. + createSchedulingRequest(2 * 1024, "queueA", "user1"); + // Queue B wants 6 * 1024 + createSchedulingRequest(6 * 1024, "queueB", "user1"); + + scheduler.update(); + + FSLeafQueue queue = scheduler.getQueueManager().getLeafQueue( + "queueA", false); + // queueA's weight is 0.0, so its fair share should be 0. + assertEquals(0, queue.getFairShare().getMemory()); + // queueB's weight is 0.0, so its fair share should be 0. + queue = scheduler.getQueueManager().getLeafQueue( + "queueB", false); + assertEquals(0, queue.getFairShare().getMemory()); + } + @Test public void testSimpleHierarchicalFairShareCalculation() throws IOException { scheduler.init(conf);