|
@@ -24,6 +24,8 @@ import org.apache.hadoop.yarn.api.records.Resource;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FSQueue;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FSQueue;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.Schedulable;
|
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.Schedulable;
|
|
|
|
|
|
|
|
+import static java.lang.Math.addExact;
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Contains logic for computing the fair shares. A {@link Schedulable}'s fair
|
|
* Contains logic for computing the fair shares. A {@link Schedulable}'s fair
|
|
* share is {@link Resource} it is entitled to, independent of the current
|
|
* share is {@link Resource} it is entitled to, independent of the current
|
|
@@ -31,10 +33,13 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.Schedulable;
|
|
* consumption lies at or below its fair share will never have its containers
|
|
* consumption lies at or below its fair share will never have its containers
|
|
* preempted.
|
|
* preempted.
|
|
*/
|
|
*/
|
|
-public class ComputeFairShares {
|
|
|
|
|
|
+public final class ComputeFairShares {
|
|
|
|
|
|
private static final int COMPUTE_FAIR_SHARES_ITERATIONS = 25;
|
|
private static final int COMPUTE_FAIR_SHARES_ITERATIONS = 25;
|
|
|
|
|
|
|
|
+ private ComputeFairShares() {
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Compute fair share of the given schedulables.Fair share is an allocation of
|
|
* Compute fair share of the given schedulables.Fair share is an allocation of
|
|
* shares considering only active schedulables ie schedulables which have
|
|
* shares considering only active schedulables ie schedulables which have
|
|
@@ -100,19 +105,20 @@ public class ComputeFairShares {
|
|
* all Schedulables are only given their minShare) and an upper bound computed
|
|
* all Schedulables are only given their minShare) and an upper bound computed
|
|
* to be large enough that too many slots are given (by doubling R until we
|
|
* to be large enough that too many slots are given (by doubling R until we
|
|
* use more than totalResources resources). The helper method
|
|
* use more than totalResources resources). The helper method
|
|
- * resourceUsedWithWeightToResourceRatio computes the total resources used with a
|
|
|
|
- * given value of R.
|
|
|
|
|
|
+ * resourceUsedWithWeightToResourceRatio computes the total resources used
|
|
|
|
+ * with a given value of R.
|
|
* <p>
|
|
* <p>
|
|
* The running time of this algorithm is linear in the number of Schedulables,
|
|
* The running time of this algorithm is linear in the number of Schedulables,
|
|
- * because resourceUsedWithWeightToResourceRatio is linear-time and the number of
|
|
|
|
- * iterations of binary search is a constant (dependent on desired precision).
|
|
|
|
|
|
+ * because resourceUsedWithWeightToResourceRatio is linear-time and the
|
|
|
|
+ * number of iterations of binary search is a constant (dependent on desired
|
|
|
|
+ * precision).
|
|
*/
|
|
*/
|
|
private static void computeSharesInternal(
|
|
private static void computeSharesInternal(
|
|
Collection<? extends Schedulable> allSchedulables,
|
|
Collection<? extends Schedulable> allSchedulables,
|
|
Resource totalResources, String type, boolean isSteadyShare) {
|
|
Resource totalResources, String type, boolean isSteadyShare) {
|
|
|
|
|
|
Collection<Schedulable> schedulables = new ArrayList<>();
|
|
Collection<Schedulable> schedulables = new ArrayList<>();
|
|
- int takenResources = handleFixedFairShares(
|
|
|
|
|
|
+ long takenResources = handleFixedFairShares(
|
|
allSchedulables, schedulables, isSteadyShare, type);
|
|
allSchedulables, schedulables, isSteadyShare, type);
|
|
|
|
|
|
if (schedulables.isEmpty()) {
|
|
if (schedulables.isEmpty()) {
|
|
@@ -121,12 +127,11 @@ public class ComputeFairShares {
|
|
// Find an upper bound on R that we can use in our binary search. We start
|
|
// Find an upper bound on R that we can use in our binary search. We start
|
|
// at R = 1 and double it until we have either used all the resources or we
|
|
// at R = 1 and double it until we have either used all the resources or we
|
|
// have met all Schedulables' max shares.
|
|
// have met all Schedulables' max shares.
|
|
- int totalMaxShare = 0;
|
|
|
|
|
|
+ long totalMaxShare = 0;
|
|
for (Schedulable sched : schedulables) {
|
|
for (Schedulable sched : schedulables) {
|
|
long maxShare = sched.getMaxShare().getResourceValue(type);
|
|
long maxShare = sched.getMaxShare().getResourceValue(type);
|
|
- totalMaxShare = (int) Math.min(maxShare + (long)totalMaxShare,
|
|
|
|
- Integer.MAX_VALUE);
|
|
|
|
- if (totalMaxShare == Integer.MAX_VALUE) {
|
|
|
|
|
|
+ totalMaxShare = safeAdd(maxShare, totalMaxShare);
|
|
|
|
+ if (totalMaxShare == Long.MAX_VALUE) {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -166,23 +171,24 @@ public class ComputeFairShares {
|
|
target = sched.getFairShare();
|
|
target = sched.getFairShare();
|
|
}
|
|
}
|
|
|
|
|
|
- target.setResourceValue(type, (long)computeShare(sched, right, type));
|
|
|
|
|
|
+ target.setResourceValue(type, computeShare(sched, right, type));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* Compute the resources that would be used given a weight-to-resource ratio
|
|
* Compute the resources that would be used given a weight-to-resource ratio
|
|
- * w2rRatio, for use in the computeFairShares algorithm as described in #
|
|
|
|
|
|
+ * w2rRatio, for use in the computeFairShares algorithm as described in
|
|
|
|
+ * {@link #computeSharesInternal}.
|
|
*/
|
|
*/
|
|
private static long resourceUsedWithWeightToResourceRatio(double w2rRatio,
|
|
private static long resourceUsedWithWeightToResourceRatio(double w2rRatio,
|
|
Collection<? extends Schedulable> schedulables, String type) {
|
|
Collection<? extends Schedulable> schedulables, String type) {
|
|
long resourcesTaken = 0;
|
|
long resourcesTaken = 0;
|
|
for (Schedulable sched : schedulables) {
|
|
for (Schedulable sched : schedulables) {
|
|
long share = computeShare(sched, w2rRatio, type);
|
|
long share = computeShare(sched, w2rRatio, type);
|
|
- if (Long.MAX_VALUE - resourcesTaken < share) {
|
|
|
|
- return Long.MAX_VALUE;
|
|
|
|
|
|
+ resourcesTaken = safeAdd(resourcesTaken, share);
|
|
|
|
+ if (resourcesTaken == Long.MAX_VALUE) {
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
- resourcesTaken += share;
|
|
|
|
}
|
|
}
|
|
return resourcesTaken;
|
|
return resourcesTaken;
|
|
}
|
|
}
|
|
@@ -204,11 +210,11 @@ public class ComputeFairShares {
|
|
* Returns the resources taken by fixed fairshare schedulables,
|
|
* Returns the resources taken by fixed fairshare schedulables,
|
|
* and adds the remaining to the passed nonFixedSchedulables.
|
|
* and adds the remaining to the passed nonFixedSchedulables.
|
|
*/
|
|
*/
|
|
- private static int handleFixedFairShares(
|
|
|
|
|
|
+ private static long handleFixedFairShares(
|
|
Collection<? extends Schedulable> schedulables,
|
|
Collection<? extends Schedulable> schedulables,
|
|
Collection<Schedulable> nonFixedSchedulables,
|
|
Collection<Schedulable> nonFixedSchedulables,
|
|
boolean isSteadyShare, String type) {
|
|
boolean isSteadyShare, String type) {
|
|
- int totalResource = 0;
|
|
|
|
|
|
+ long totalResource = 0;
|
|
|
|
|
|
for (Schedulable sched : schedulables) {
|
|
for (Schedulable sched : schedulables) {
|
|
long fixedShare = getFairShareIfFixed(sched, isSteadyShare, type);
|
|
long fixedShare = getFairShareIfFixed(sched, isSteadyShare, type);
|
|
@@ -224,15 +230,15 @@ public class ComputeFairShares {
|
|
}
|
|
}
|
|
|
|
|
|
target.setResourceValue(type, fixedShare);
|
|
target.setResourceValue(type, fixedShare);
|
|
- totalResource = (int) Math.min((long)totalResource + (long)fixedShare,
|
|
|
|
- Integer.MAX_VALUE);
|
|
|
|
|
|
+ totalResource = safeAdd(totalResource, fixedShare);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return totalResource;
|
|
return totalResource;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Get the fairshare for the {@link Schedulable} if it is fixed, -1 otherwise.
|
|
|
|
|
|
+ * Get the fairshare for the {@link Schedulable} if it is fixed,
|
|
|
|
+ * -1 otherwise.
|
|
*
|
|
*
|
|
* The fairshare is fixed if either the maxShare is 0, weight is 0,
|
|
* The fairshare is fixed if either the maxShare is 0, weight is 0,
|
|
* or the Schedulable is not active for instantaneous fairshare.
|
|
* or the Schedulable is not active for instantaneous fairshare.
|
|
@@ -259,4 +265,20 @@ public class ComputeFairShares {
|
|
|
|
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Safely add two long values. The result will always be a valid long value.
|
|
|
|
+ * If the addition caused an overflow the return value will be set to
|
|
|
|
+ * <code>Long.MAX_VALUE</code>.
|
|
|
|
+ * @param a first long to add
|
|
|
|
+ * @param b second long to add
|
|
|
|
+ * @return result of the addition
|
|
|
|
+ */
|
|
|
|
+ private static long safeAdd(long a, long b) {
|
|
|
|
+ try {
|
|
|
|
+ return addExact(a, b);
|
|
|
|
+ } catch (ArithmeticException ae) {
|
|
|
|
+ return Long.MAX_VALUE;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|