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/fair/policies/FairSharePolicy.java b/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 c3ec47a..4af8e09 100644 --- a/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 +++ b/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 @@ -79,6 +79,18 @@ public String getName() { @Override public int compare(Schedulable s1, Schedulable s2) { + Resource demand1 = s1.getDemand(); + Resource demand2 = s2.getDemand(); + // Put the schedulable which does not require resource to + // the end. So the other schedulable can get resource as soon as + // possible though it use resource greater then it minShare or demand. + if (demand1.equals(Resources.none()) && + !demand2.equals(Resources.none())) { + return 1; + } else if (demand2.equals(Resources.none()) && + !demand1.equals(Resources.none())) { + return -1; + } double minShareRatio1, minShareRatio2; double useToWeightRatio1, useToWeightRatio2; double weight1, weight2; @@ -86,9 +98,9 @@ public int compare(Schedulable s1, Schedulable s2) { Resource resourceUsage1 = s1.getResourceUsage(); Resource resourceUsage2 = s2.getResourceUsage(); Resource minShare1 = Resources.min(RESOURCE_CALCULATOR, null, - s1.getMinShare(), s1.getDemand()); + s1.getMinShare(), demand1); Resource minShare2 = Resources.min(RESOURCE_CALCULATOR, null, - s2.getMinShare(), s2.getDemand()); + s2.getMinShare(), demand2); boolean s1Needy = Resources.lessThan(RESOURCE_CALCULATOR, null, resourceUsage1, minShare1); boolean s2Needy = Resources.lessThan(RESOURCE_CALCULATOR, null, 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/fair/TestSchedulingPolicy.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestSchedulingPolicy.java index d84f0cf..c3450fe 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestSchedulingPolicy.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestSchedulingPolicy.java @@ -122,7 +122,8 @@ public void testFairShareComparatorTransitivity() { // Use the following data collections to generate three Schedulable. private Resource minShare = Resource.newInstance(0, 1); - private Resource demand = Resource.newInstance(4, 1); + private Resource[] demandCollection = { + Resource.newInstance(0, 0), Resource.newInstance(4, 1) }; private String[] nameCollection = {"A", "B", "C"}; @@ -148,8 +149,8 @@ public void testTransitivity() { } private void generateAndTest(Stack genSchedulable) { - if (genSchedulable.size() == 3) { - // We get three Schedulable objects, let's use them to check the + if (genSchedulable.size() == 4) { + // We get four Schedulable objects, let's use them to check the // comparator. Assert.assertTrue("The comparator must ensure transitivity", checkTransitivity(genSchedulable)); @@ -160,9 +161,11 @@ private void generateAndTest(Stack genSchedulable) { for (int j = 0; j < startTimeColloection.length; j++) { for (int k = 0; k < usageCollection.length; k++) { for (int t = 0; t < weightsCollection.length; t++) { - genSchedulable.push(createSchedulable(i, j, k, t)); - generateAndTest(genSchedulable); - genSchedulable.pop(); + for (int m = 0; m < demandCollection.length; m++) { + genSchedulable.push(createSchedulable(m, i, j, k, t)); + generateAndTest(genSchedulable); + genSchedulable.pop(); + } } } } @@ -171,8 +174,8 @@ private void generateAndTest(Stack genSchedulable) { } private Schedulable createSchedulable( - int nameIdx, int startTimeIdx, int usageIdx, int weightsIdx) { - return new MockSchedulable(minShare, demand, nameCollection[nameIdx], + int demandId, int nameIdx, int startTimeIdx, int usageIdx, int weightsIdx) { + return new MockSchedulable(minShare, demandCollection[demandId], nameCollection[nameIdx], startTimeColloection[startTimeIdx], usageCollection[usageIdx], weightsCollection[weightsIdx]); } @@ -180,29 +183,32 @@ private Schedulable createSchedulable( private boolean checkTransitivity( Collection schedulableObjs) { - Assert.assertEquals(3, schedulableObjs.size()); - Schedulable[] copy = schedulableObjs.toArray(new Schedulable[3]); + Assert.assertEquals(4, schedulableObjs.size()); + Schedulable[] copy = schedulableObjs.toArray(new Schedulable[4]); - if (fairShareComparator.compare(copy[0], copy[1]) > 0) { - swap(copy, 0, 1); - } - - if (fairShareComparator.compare(copy[1], copy[2]) > 0) { - swap(copy, 1, 2); - - if (fairShareComparator.compare(copy[0], copy[1]) > 0) { - swap(copy, 0, 1); + for (int i = 3; i > 0; i--) { + Schedulable curMaxSchedulable = copy[i]; + int curIndex = i; + for (int j = 0; j < i; j++) { + if (fairShareComparator.compare(copy[j], curMaxSchedulable) > 0) { + curMaxSchedulable = copy[j]; + curIndex = j; + } } - } + if (curIndex != i) { + swap(copy, i, curIndex); + } + } // Here, we have got the following condition: - // copy[0] <= copy[1] && copy[1] <= copy[2] + // copy[0] <= copy[1] && copy[1] <= copy[2] && copy[2] <= copy[3] // - // So, just check copy[0] <= copy[2] - if (fairShareComparator.compare(copy[0], copy[2]) <= 0) { + // So, just check copy[0] <= copy[3] + if (fairShareComparator.compare(copy[0], copy[3]) <= 0) { return true; } else { - LOG.fatal("Failure data: " + copy[0] + " " + copy[1] + " " + copy[2]); + LOG.fatal("Failure data: " + copy[0] + " " + copy[1] + " " + + copy[2] + " " + copy[3]); return false; } }