|
@@ -51,6 +51,7 @@ import org.apache.hadoop.metrics2.lib.Interns;
|
|
import org.apache.hadoop.metrics2.util.MBeans;
|
|
import org.apache.hadoop.metrics2.util.MBeans;
|
|
import org.apache.hadoop.metrics2.util.Metrics2Util.NameValuePair;
|
|
import org.apache.hadoop.metrics2.util.Metrics2Util.NameValuePair;
|
|
import org.apache.hadoop.metrics2.util.Metrics2Util.TopN;
|
|
import org.apache.hadoop.metrics2.util.Metrics2Util.TopN;
|
|
|
|
+import org.apache.hadoop.security.UserGroupInformation;
|
|
|
|
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.Logger;
|
|
@@ -172,7 +173,7 @@ public class DecayRpcScheduler implements RpcScheduler,
|
|
private static final double PRECISION = 0.0001;
|
|
private static final double PRECISION = 0.0001;
|
|
private MetricsProxy metricsProxy;
|
|
private MetricsProxy metricsProxy;
|
|
private final CostProvider costProvider;
|
|
private final CostProvider costProvider;
|
|
-
|
|
|
|
|
|
+ private final Map<String,Integer> staticPriorities = new HashMap<>();
|
|
/**
|
|
/**
|
|
* This TimerTask will call decayCurrentCosts until
|
|
* This TimerTask will call decayCurrentCosts until
|
|
* the scheduler has been garbage collected.
|
|
* the scheduler has been garbage collected.
|
|
@@ -468,7 +469,7 @@ public class DecayRpcScheduler implements RpcScheduler,
|
|
AtomicLong value = entry.getValue().get(0);
|
|
AtomicLong value = entry.getValue().get(0);
|
|
|
|
|
|
long snapshot = value.get();
|
|
long snapshot = value.get();
|
|
- int computedLevel = computePriorityLevel(snapshot);
|
|
|
|
|
|
+ int computedLevel = computePriorityLevel(snapshot, id);
|
|
|
|
|
|
nextCache.put(id, computedLevel);
|
|
nextCache.put(id, computedLevel);
|
|
}
|
|
}
|
|
@@ -515,10 +516,15 @@ public class DecayRpcScheduler implements RpcScheduler,
|
|
/**
|
|
/**
|
|
* Given the cost for an identity, compute a scheduling decision.
|
|
* Given the cost for an identity, compute a scheduling decision.
|
|
*
|
|
*
|
|
|
|
+ * @param identity to compute a cost
|
|
* @param cost the cost for an identity
|
|
* @param cost the cost for an identity
|
|
* @return scheduling decision from 0 to numLevels - 1
|
|
* @return scheduling decision from 0 to numLevels - 1
|
|
*/
|
|
*/
|
|
- private int computePriorityLevel(long cost) {
|
|
|
|
|
|
+ private int computePriorityLevel(long cost, Object identity) {
|
|
|
|
+ Integer staticPriority = staticPriorities.get(identity);
|
|
|
|
+ if (staticPriority != null) {
|
|
|
|
+ return staticPriority.intValue();
|
|
|
|
+ }
|
|
long totalCallSnapshot = totalDecayedCallCost.get();
|
|
long totalCallSnapshot = totalDecayedCallCost.get();
|
|
|
|
|
|
double proportion = 0;
|
|
double proportion = 0;
|
|
@@ -558,11 +564,20 @@ public class DecayRpcScheduler implements RpcScheduler,
|
|
// Cache was no good, compute it
|
|
// Cache was no good, compute it
|
|
List<AtomicLong> costList = callCosts.get(identity);
|
|
List<AtomicLong> costList = callCosts.get(identity);
|
|
long currentCost = costList == null ? 0 : costList.get(0).get();
|
|
long currentCost = costList == null ? 0 : costList.get(0).get();
|
|
- int priority = computePriorityLevel(currentCost);
|
|
|
|
|
|
+ int priority = computePriorityLevel(currentCost, identity);
|
|
LOG.debug("compute priority for {} priority {}", identity, priority);
|
|
LOG.debug("compute priority for {} priority {}", identity, priority);
|
|
return priority;
|
|
return priority;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private String getIdentity(Schedulable obj) {
|
|
|
|
+ String identity = this.identityProvider.makeIdentity(obj);
|
|
|
|
+ if (identity == null) {
|
|
|
|
+ // Identity provider did not handle this
|
|
|
|
+ identity = DECAYSCHEDULER_UNKNOWN_IDENTITY;
|
|
|
|
+ }
|
|
|
|
+ return identity;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Compute the appropriate priority for a schedulable based on past requests.
|
|
* Compute the appropriate priority for a schedulable based on past requests.
|
|
* @param obj the schedulable obj to query and remember
|
|
* @param obj the schedulable obj to query and remember
|
|
@@ -571,15 +586,41 @@ public class DecayRpcScheduler implements RpcScheduler,
|
|
@Override
|
|
@Override
|
|
public int getPriorityLevel(Schedulable obj) {
|
|
public int getPriorityLevel(Schedulable obj) {
|
|
// First get the identity
|
|
// First get the identity
|
|
- String identity = this.identityProvider.makeIdentity(obj);
|
|
|
|
- if (identity == null) {
|
|
|
|
- // Identity provider did not handle this
|
|
|
|
- identity = DECAYSCHEDULER_UNKNOWN_IDENTITY;
|
|
|
|
- }
|
|
|
|
|
|
+ String identity = getIdentity(obj);
|
|
|
|
+ // highest priority users may have a negative priority but their
|
|
|
|
+ // calls will be priority 0.
|
|
|
|
+ return Math.max(0, cachedOrComputedPriorityLevel(identity));
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ @VisibleForTesting
|
|
|
|
+ int getPriorityLevel(UserGroupInformation ugi) {
|
|
|
|
+ String identity = getIdentity(newSchedulable(ugi));
|
|
|
|
+ // returns true priority of the user.
|
|
return cachedOrComputedPriorityLevel(identity);
|
|
return cachedOrComputedPriorityLevel(identity);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @VisibleForTesting
|
|
|
|
+ void setPriorityLevel(UserGroupInformation ugi, int priority) {
|
|
|
|
+ String identity = getIdentity(newSchedulable(ugi));
|
|
|
|
+ priority = Math.min(numLevels - 1, priority);
|
|
|
|
+ LOG.info("Setting priority for user:" + identity + "=" + priority);
|
|
|
|
+ staticPriorities.put(identity, priority);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // dummy instance to conform to identity provider api.
|
|
|
|
+ private static Schedulable newSchedulable(UserGroupInformation ugi) {
|
|
|
|
+ return new Schedulable() {
|
|
|
|
+ @Override
|
|
|
|
+ public UserGroupInformation getUserGroupInformation() {
|
|
|
|
+ return ugi;
|
|
|
|
+ }
|
|
|
|
+ @Override
|
|
|
|
+ public int getPriorityLevel() {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public boolean shouldBackOff(Schedulable obj) {
|
|
public boolean shouldBackOff(Schedulable obj) {
|
|
Boolean backOff = false;
|
|
Boolean backOff = false;
|