YARN-3124. Fixed CS LeafQueue/ParentQueue to use QueueCapacities to track capacities-by-label. Contributed by Wangda Tan
This commit is contained in:
parent
11d8934463
commit
18a594257e
|
@ -281,6 +281,9 @@ Release 2.7.0 - UNRELEASED
|
||||||
|
|
||||||
YARN-3181. FairScheduler: Fix up outdated findbugs issues. (kasha)
|
YARN-3181. FairScheduler: Fix up outdated findbugs issues. (kasha)
|
||||||
|
|
||||||
|
YARN-3124. Fixed CS LeafQueue/ParentQueue to use QueueCapacities to track
|
||||||
|
capacities-by-label. (Wangda Tan via jianhe)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
YARN-2990. FairScheduler's delay-scheduling always waits for node-local and
|
YARN-2990. FairScheduler's delay-scheduling always waits for node-local and
|
||||||
|
|
|
@ -194,6 +194,8 @@
|
||||||
<Field name="absoluteNodeLabelCapacities" />
|
<Field name="absoluteNodeLabelCapacities" />
|
||||||
<Field name="reservationsContinueLooking" />
|
<Field name="reservationsContinueLooking" />
|
||||||
<Field name="absoluteCapacityByNodeLabels" />
|
<Field name="absoluteCapacityByNodeLabels" />
|
||||||
|
<Field name="authorizer" />
|
||||||
|
<Field name="parent" />
|
||||||
</Or>
|
</Or>
|
||||||
<Bug pattern="IS2_INCONSISTENT_SYNC" />
|
<Bug pattern="IS2_INCONSISTENT_SYNC" />
|
||||||
</Match>
|
</Match>
|
||||||
|
|
|
@ -44,23 +44,15 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceUsage;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerUtils;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerUtils;
|
||||||
import org.apache.hadoop.yarn.util.resource.ResourceCalculator;
|
import org.apache.hadoop.yarn.util.resource.ResourceCalculator;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
public abstract class AbstractCSQueue implements CSQueue {
|
public abstract class AbstractCSQueue implements CSQueue {
|
||||||
|
|
||||||
CSQueue parent;
|
CSQueue parent;
|
||||||
final String queueName;
|
final String queueName;
|
||||||
float capacity;
|
|
||||||
float maximumCapacity;
|
|
||||||
float absoluteCapacity;
|
|
||||||
float absoluteMaxCapacity;
|
|
||||||
float absoluteUsedCapacity = 0.0f;
|
|
||||||
|
|
||||||
float usedCapacity = 0.0f;
|
|
||||||
volatile int numContainers;
|
volatile int numContainers;
|
||||||
|
|
||||||
final Resource minimumAllocation;
|
Resource minimumAllocation;
|
||||||
Resource maximumAllocation;
|
Resource maximumAllocation;
|
||||||
QueueState state;
|
QueueState state;
|
||||||
final QueueMetrics metrics;
|
final QueueMetrics metrics;
|
||||||
|
@ -70,10 +62,6 @@ public abstract class AbstractCSQueue implements CSQueue {
|
||||||
Set<String> accessibleLabels;
|
Set<String> accessibleLabels;
|
||||||
RMNodeLabelsManager labelManager;
|
RMNodeLabelsManager labelManager;
|
||||||
String defaultLabelExpression;
|
String defaultLabelExpression;
|
||||||
Map<String, Float> absoluteCapacityByNodeLabels;
|
|
||||||
Map<String, Float> capacitiyByNodeLabels;
|
|
||||||
Map<String, Float> absoluteMaxCapacityByNodeLabels;
|
|
||||||
Map<String, Float> maxCapacityByNodeLabels;
|
|
||||||
|
|
||||||
Map<AccessType, AccessControlList> acls =
|
Map<AccessType, AccessControlList> acls =
|
||||||
new HashMap<AccessType, AccessControlList>();
|
new HashMap<AccessType, AccessControlList>();
|
||||||
|
@ -83,15 +71,17 @@ public abstract class AbstractCSQueue implements CSQueue {
|
||||||
// Track resource usage-by-label like used-resource/pending-resource, etc.
|
// Track resource usage-by-label like used-resource/pending-resource, etc.
|
||||||
ResourceUsage queueUsage;
|
ResourceUsage queueUsage;
|
||||||
|
|
||||||
|
// Track capacities like used-capcity/abs-used-capacity/capacity/abs-capacity,
|
||||||
|
// etc.
|
||||||
|
QueueCapacities queueCapacities;
|
||||||
|
|
||||||
private final RecordFactory recordFactory =
|
private final RecordFactory recordFactory =
|
||||||
RecordFactoryProvider.getRecordFactory(null);
|
RecordFactoryProvider.getRecordFactory(null);
|
||||||
private CapacitySchedulerContext csContext;
|
protected CapacitySchedulerContext csContext;
|
||||||
protected YarnAuthorizationProvider authorizer = null;
|
protected YarnAuthorizationProvider authorizer = null;
|
||||||
|
|
||||||
public AbstractCSQueue(CapacitySchedulerContext cs,
|
public AbstractCSQueue(CapacitySchedulerContext cs,
|
||||||
String queueName, CSQueue parent, CSQueue old) throws IOException {
|
String queueName, CSQueue parent, CSQueue old) throws IOException {
|
||||||
this.minimumAllocation = cs.getMinimumResourceCapability();
|
|
||||||
this.maximumAllocation = cs.getMaximumResourceCapability();
|
|
||||||
this.labelManager = cs.getRMContext().getNodeLabelManager();
|
this.labelManager = cs.getRMContext().getNodeLabelManager();
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.queueName = queueName;
|
this.queueName = queueName;
|
||||||
|
@ -102,68 +92,55 @@ public abstract class AbstractCSQueue implements CSQueue {
|
||||||
QueueMetrics.forQueue(getQueuePath(), parent,
|
QueueMetrics.forQueue(getQueuePath(), parent,
|
||||||
cs.getConfiguration().getEnableUserMetrics(),
|
cs.getConfiguration().getEnableUserMetrics(),
|
||||||
cs.getConf());
|
cs.getConf());
|
||||||
|
|
||||||
// get labels
|
|
||||||
this.accessibleLabels = cs.getConfiguration().getAccessibleNodeLabels(getQueuePath());
|
|
||||||
this.defaultLabelExpression = cs.getConfiguration()
|
|
||||||
.getDefaultNodeLabelExpression(getQueuePath());
|
|
||||||
|
|
||||||
// inherit from parent if labels not set
|
|
||||||
if (this.accessibleLabels == null && parent != null) {
|
|
||||||
this.accessibleLabels = parent.getAccessibleNodeLabels();
|
|
||||||
}
|
|
||||||
SchedulerUtils.checkIfLabelInClusterNodeLabels(labelManager,
|
|
||||||
this.accessibleLabels);
|
|
||||||
|
|
||||||
// inherit from parent if labels not set
|
|
||||||
if (this.defaultLabelExpression == null && parent != null
|
|
||||||
&& this.accessibleLabels.containsAll(parent.getAccessibleNodeLabels())) {
|
|
||||||
this.defaultLabelExpression = parent.getDefaultNodeLabelExpression();
|
|
||||||
}
|
|
||||||
|
|
||||||
// set capacity by labels
|
|
||||||
capacitiyByNodeLabels =
|
|
||||||
cs.getConfiguration().getNodeLabelCapacities(getQueuePath(), accessibleLabels,
|
|
||||||
labelManager);
|
|
||||||
|
|
||||||
// set maximum capacity by labels
|
|
||||||
maxCapacityByNodeLabels =
|
|
||||||
cs.getConfiguration().getMaximumNodeLabelCapacities(getQueuePath(),
|
|
||||||
accessibleLabels, labelManager);
|
|
||||||
this.csContext = cs;
|
this.csContext = cs;
|
||||||
|
|
||||||
|
// initialize ResourceUsage
|
||||||
queueUsage = new ResourceUsage();
|
queueUsage = new ResourceUsage();
|
||||||
queueEntity = new PrivilegedEntity(EntityType.QUEUE, getQueuePath());
|
queueEntity = new PrivilegedEntity(EntityType.QUEUE, getQueuePath());
|
||||||
authorizer = YarnAuthorizationProvider.getInstance(cs.getConf());
|
|
||||||
|
// initialize QueueCapacities
|
||||||
|
queueCapacities = new QueueCapacities(parent == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setupConfigurableCapacities() {
|
||||||
|
CSQueueUtils.loadUpdateAndCheckCapacities(
|
||||||
|
getQueuePath(),
|
||||||
|
accessibleLabels,
|
||||||
|
csContext.getConfiguration(),
|
||||||
|
queueCapacities,
|
||||||
|
parent == null ? null : parent.getQueueCapacities(),
|
||||||
|
csContext.getRMContext().getNodeLabelManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized float getCapacity() {
|
public synchronized float getCapacity() {
|
||||||
return capacity;
|
return queueCapacities.getCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized float getAbsoluteCapacity() {
|
public synchronized float getAbsoluteCapacity() {
|
||||||
return absoluteCapacity;
|
return queueCapacities.getAbsoluteCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getAbsoluteMaximumCapacity() {
|
public float getAbsoluteMaximumCapacity() {
|
||||||
return absoluteMaxCapacity;
|
return queueCapacities.getAbsoluteMaximumCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized float getAbsoluteUsedCapacity() {
|
public synchronized float getAbsoluteUsedCapacity() {
|
||||||
return absoluteUsedCapacity;
|
return queueCapacities.getAbsoluteUsedCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getMaximumCapacity() {
|
public float getMaximumCapacity() {
|
||||||
return maximumCapacity;
|
return queueCapacities.getMaximumCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized float getUsedCapacity() {
|
public synchronized float getUsedCapacity() {
|
||||||
return usedCapacity;
|
return queueCapacities.getUsedCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -216,12 +193,12 @@ public abstract class AbstractCSQueue implements CSQueue {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void setUsedCapacity(float usedCapacity) {
|
public synchronized void setUsedCapacity(float usedCapacity) {
|
||||||
this.usedCapacity = usedCapacity;
|
queueCapacities.setUsedCapacity(usedCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void setAbsoluteUsedCapacity(float absUsedCapacity) {
|
public synchronized void setAbsoluteUsedCapacity(float absUsedCapacity) {
|
||||||
this.absoluteUsedCapacity = absUsedCapacity;
|
queueCapacities.setAbsoluteUsedCapacity(absUsedCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -230,21 +207,16 @@ public abstract class AbstractCSQueue implements CSQueue {
|
||||||
*/
|
*/
|
||||||
synchronized void setMaxCapacity(float maximumCapacity) {
|
synchronized void setMaxCapacity(float maximumCapacity) {
|
||||||
// Sanity check
|
// Sanity check
|
||||||
CSQueueUtils.checkMaxCapacity(getQueueName(), capacity, maximumCapacity);
|
CSQueueUtils.checkMaxCapacity(getQueueName(),
|
||||||
|
queueCapacities.getCapacity(), maximumCapacity);
|
||||||
float absMaxCapacity =
|
float absMaxCapacity =
|
||||||
CSQueueUtils.computeAbsoluteMaximumCapacity(maximumCapacity, parent);
|
CSQueueUtils.computeAbsoluteMaximumCapacity(maximumCapacity, parent);
|
||||||
CSQueueUtils.checkAbsoluteCapacity(getQueueName(), absoluteCapacity,
|
CSQueueUtils.checkAbsoluteCapacity(getQueueName(),
|
||||||
|
queueCapacities.getAbsoluteCapacity(),
|
||||||
absMaxCapacity);
|
absMaxCapacity);
|
||||||
|
|
||||||
this.maximumCapacity = maximumCapacity;
|
queueCapacities.setMaximumCapacity(maximumCapacity);
|
||||||
this.absoluteMaxCapacity = absMaxCapacity;
|
queueCapacities.setAbsoluteMaximumCapacity(absMaxCapacity);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getAbsActualCapacity() {
|
|
||||||
// for now, simply return actual capacity = guaranteed capacity for parent
|
|
||||||
// queue
|
|
||||||
return absoluteCapacity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -252,39 +224,39 @@ public abstract class AbstractCSQueue implements CSQueue {
|
||||||
return defaultLabelExpression;
|
return defaultLabelExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void setupQueueConfigs(Resource clusterResource, float capacity,
|
synchronized void setupQueueConfigs(Resource clusterResource)
|
||||||
float absoluteCapacity, float maximumCapacity, float absoluteMaxCapacity,
|
|
||||||
QueueState state, Map<AccessType, AccessControlList> acls,
|
|
||||||
Set<String> labels, String defaultLabelExpression,
|
|
||||||
Map<String, Float> nodeLabelCapacities,
|
|
||||||
Map<String, Float> maximumNodeLabelCapacities,
|
|
||||||
boolean reservationContinueLooking, Resource maxAllocation)
|
|
||||||
throws IOException {
|
throws IOException {
|
||||||
// Sanity check
|
// get labels
|
||||||
CSQueueUtils.checkMaxCapacity(getQueueName(), capacity, maximumCapacity);
|
this.accessibleLabels =
|
||||||
CSQueueUtils.checkAbsoluteCapacity(getQueueName(), absoluteCapacity,
|
csContext.getConfiguration().getAccessibleNodeLabels(getQueuePath());
|
||||||
absoluteMaxCapacity);
|
this.defaultLabelExpression = csContext.getConfiguration()
|
||||||
|
.getDefaultNodeLabelExpression(getQueuePath());
|
||||||
|
|
||||||
this.capacity = capacity;
|
// inherit from parent if labels not set
|
||||||
this.absoluteCapacity = absoluteCapacity;
|
if (this.accessibleLabels == null && parent != null) {
|
||||||
|
this.accessibleLabels = parent.getAccessibleNodeLabels();
|
||||||
this.maximumCapacity = maximumCapacity;
|
}
|
||||||
this.absoluteMaxCapacity = absoluteMaxCapacity;
|
SchedulerUtils.checkIfLabelInClusterNodeLabels(labelManager,
|
||||||
|
this.accessibleLabels);
|
||||||
this.state = state;
|
|
||||||
|
|
||||||
this.acls = acls;
|
|
||||||
|
|
||||||
// set labels
|
// inherit from parent if labels not set
|
||||||
this.accessibleLabels = labels;
|
if (this.defaultLabelExpression == null && parent != null
|
||||||
|
&& this.accessibleLabels.containsAll(parent.getAccessibleNodeLabels())) {
|
||||||
|
this.defaultLabelExpression = parent.getDefaultNodeLabelExpression();
|
||||||
|
}
|
||||||
|
|
||||||
|
// After we setup labels, we can setup capacities
|
||||||
|
setupConfigurableCapacities();
|
||||||
|
|
||||||
// set label expression
|
this.minimumAllocation = csContext.getMinimumResourceCapability();
|
||||||
this.defaultLabelExpression = defaultLabelExpression;
|
this.maximumAllocation =
|
||||||
|
csContext.getConfiguration().getMaximumAllocationPerQueue(
|
||||||
|
getQueuePath());
|
||||||
|
|
||||||
// copy node label capacity
|
authorizer = YarnAuthorizationProvider.getInstance(csContext.getConf());
|
||||||
this.capacitiyByNodeLabels = new HashMap<String, Float>(nodeLabelCapacities);
|
|
||||||
this.maxCapacityByNodeLabels =
|
this.state = csContext.getConfiguration().getState(getQueuePath());
|
||||||
new HashMap<String, Float>(maximumNodeLabelCapacities);
|
this.acls = csContext.getConfiguration().getAcls(getQueuePath());
|
||||||
|
|
||||||
// Update metrics
|
// Update metrics
|
||||||
CSQueueUtils.updateQueueStatistics(
|
CSQueueUtils.updateQueueStatistics(
|
||||||
|
@ -311,34 +283,19 @@ public abstract class AbstractCSQueue implements CSQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate absolute capacity by each node label
|
this.reservationsContinueLooking = csContext.getConfiguration()
|
||||||
this.absoluteCapacityByNodeLabels =
|
.getReservationContinueLook();
|
||||||
CSQueueUtils.computeAbsoluteCapacityByNodeLabels(
|
|
||||||
this.capacitiyByNodeLabels, parent);
|
|
||||||
|
|
||||||
// calculate maximum capacity by each node label
|
|
||||||
this.absoluteMaxCapacityByNodeLabels =
|
|
||||||
CSQueueUtils.computeAbsoluteMaxCapacityByNodeLabels(
|
|
||||||
maximumNodeLabelCapacities, parent);
|
|
||||||
|
|
||||||
// check absoluteMaximumNodeLabelCapacities is valid
|
|
||||||
CSQueueUtils.checkAbsoluteCapacitiesByLabel(getQueueName(),
|
|
||||||
absoluteCapacityByNodeLabels, absoluteCapacityByNodeLabels);
|
|
||||||
|
|
||||||
this.reservationsContinueLooking = reservationContinueLooking;
|
|
||||||
|
|
||||||
this.preemptionDisabled = isQueueHierarchyPreemptionDisabled(this);
|
this.preemptionDisabled = isQueueHierarchyPreemptionDisabled(this);
|
||||||
|
|
||||||
this.maximumAllocation = maxAllocation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected QueueInfo getQueueInfo() {
|
protected QueueInfo getQueueInfo() {
|
||||||
QueueInfo queueInfo = recordFactory.newRecordInstance(QueueInfo.class);
|
QueueInfo queueInfo = recordFactory.newRecordInstance(QueueInfo.class);
|
||||||
queueInfo.setQueueName(queueName);
|
queueInfo.setQueueName(queueName);
|
||||||
queueInfo.setAccessibleNodeLabels(accessibleLabels);
|
queueInfo.setAccessibleNodeLabels(accessibleLabels);
|
||||||
queueInfo.setCapacity(capacity);
|
queueInfo.setCapacity(queueCapacities.getCapacity());
|
||||||
queueInfo.setMaximumCapacity(maximumCapacity);
|
queueInfo.setMaximumCapacity(queueCapacities.getMaximumCapacity());
|
||||||
queueInfo.setQueueState(state);
|
queueInfo.setQueueState(state);
|
||||||
queueInfo.setDefaultNodeLabelExpression(defaultLabelExpression);
|
queueInfo.setDefaultNodeLabelExpression(defaultLabelExpression);
|
||||||
queueInfo.setCurrentCapacity(getUsedCapacity());
|
queueInfo.setCurrentCapacity(getUsedCapacity());
|
||||||
|
@ -388,51 +345,6 @@ public abstract class AbstractCSQueue implements CSQueue {
|
||||||
--numContainers;
|
--numContainers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Private
|
|
||||||
public float getCapacityByNodeLabel(String label) {
|
|
||||||
if (StringUtils.equals(label, RMNodeLabelsManager.NO_LABEL)) {
|
|
||||||
if (null == parent) {
|
|
||||||
return 1f;
|
|
||||||
}
|
|
||||||
return getCapacity();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!capacitiyByNodeLabels.containsKey(label)) {
|
|
||||||
return 0f;
|
|
||||||
} else {
|
|
||||||
return capacitiyByNodeLabels.get(label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Private
|
|
||||||
public float getAbsoluteCapacityByNodeLabel(String label) {
|
|
||||||
if (StringUtils.equals(label, RMNodeLabelsManager.NO_LABEL)) {
|
|
||||||
if (null == parent) {
|
|
||||||
return 1f;
|
|
||||||
}
|
|
||||||
return getAbsoluteCapacity();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!absoluteCapacityByNodeLabels.containsKey(label)) {
|
|
||||||
return 0f;
|
|
||||||
} else {
|
|
||||||
return absoluteCapacityByNodeLabels.get(label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Private
|
|
||||||
public float getAbsoluteMaximumCapacityByNodeLabel(String label) {
|
|
||||||
if (StringUtils.equals(label, RMNodeLabelsManager.NO_LABEL)) {
|
|
||||||
return getAbsoluteMaximumCapacity();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!absoluteMaxCapacityByNodeLabels.containsKey(label)) {
|
|
||||||
return 0f;
|
|
||||||
} else {
|
|
||||||
return absoluteMaxCapacityByNodeLabels.get(label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Private
|
@Private
|
||||||
public boolean getReservationContinueLooking() {
|
public boolean getReservationContinueLooking() {
|
||||||
return reservationsContinueLooking;
|
return reservationsContinueLooking;
|
||||||
|
@ -442,21 +354,21 @@ public abstract class AbstractCSQueue implements CSQueue {
|
||||||
public Map<AccessType, AccessControlList> getACLs() {
|
public Map<AccessType, AccessControlList> getACLs() {
|
||||||
return acls;
|
return acls;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Private
|
|
||||||
public Resource getUsedResourceByLabel(String nodeLabel) {
|
|
||||||
return queueUsage.getUsed(nodeLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public ResourceUsage getResourceUsage() {
|
|
||||||
return queueUsage;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Private
|
@Private
|
||||||
public boolean getPreemptionDisabled() {
|
public boolean getPreemptionDisabled() {
|
||||||
return preemptionDisabled;
|
return preemptionDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Private
|
||||||
|
public QueueCapacities getQueueCapacities() {
|
||||||
|
return queueCapacities;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Private
|
||||||
|
public ResourceUsage getQueueResourceUsage() {
|
||||||
|
return queueUsage;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The specified queue is preemptable if system-wide preemption is turned on
|
* The specified queue is preemptable if system-wide preemption is turned on
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.hadoop.yarn.api.records.Resource;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainer;
|
import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainer;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainerEventType;
|
import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainerEventType;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ActiveUsersManager;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ActiveUsersManager;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceUsage;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.common.fica.FiCaSchedulerApp;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.common.fica.FiCaSchedulerApp;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.common.fica.FiCaSchedulerNode;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.common.fica.FiCaSchedulerNode;
|
||||||
|
|
||||||
|
@ -75,15 +76,6 @@ extends org.apache.hadoop.yarn.server.resourcemanager.scheduler.Queue {
|
||||||
* @return configured queue capacity
|
* @return configured queue capacity
|
||||||
*/
|
*/
|
||||||
public float getCapacity();
|
public float getCapacity();
|
||||||
|
|
||||||
/**
|
|
||||||
* Get actual <em>capacity</em> of the queue, this may be different from
|
|
||||||
* configured capacity when mis-config take place, like add labels to the
|
|
||||||
* cluster
|
|
||||||
*
|
|
||||||
* @return actual queue capacity
|
|
||||||
*/
|
|
||||||
public float getAbsActualCapacity();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get capacity of the parent of the queue as a function of the
|
* Get capacity of the parent of the queue as a function of the
|
||||||
|
@ -143,14 +135,6 @@ extends org.apache.hadoop.yarn.server.resourcemanager.scheduler.Queue {
|
||||||
*/
|
*/
|
||||||
public Resource getUsedResources();
|
public Resource getUsedResources();
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the currently utilized resources which allocated at nodes with label
|
|
||||||
* specified
|
|
||||||
*
|
|
||||||
* @return used resources by the queue and it's children
|
|
||||||
*/
|
|
||||||
public Resource getUsedResourceByLabel(String nodeLabel);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current run-state of the queue
|
* Get the current run-state of the queue
|
||||||
* @return current run-state
|
* @return current run-state
|
||||||
|
@ -279,31 +263,22 @@ extends org.apache.hadoop.yarn.server.resourcemanager.scheduler.Queue {
|
||||||
*/
|
*/
|
||||||
public void attachContainer(Resource clusterResource,
|
public void attachContainer(Resource clusterResource,
|
||||||
FiCaSchedulerApp application, RMContainer container);
|
FiCaSchedulerApp application, RMContainer container);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get absolute capacity by label of this queue can use
|
|
||||||
* @param nodeLabel
|
|
||||||
* @return absolute capacity by label of this queue can use
|
|
||||||
*/
|
|
||||||
public float getAbsoluteCapacityByNodeLabel(String nodeLabel);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get absolute max capacity by label of this queue can use
|
|
||||||
* @param nodeLabel
|
|
||||||
* @return absolute capacity by label of this queue can use
|
|
||||||
*/
|
|
||||||
public float getAbsoluteMaximumCapacityByNodeLabel(String nodeLabel);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get capacity by node label
|
|
||||||
* @param nodeLabel
|
|
||||||
* @return capacity by node label
|
|
||||||
*/
|
|
||||||
public float getCapacityByNodeLabel(String nodeLabel);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether <em>disable_preemption</em> property is set for this queue
|
* Check whether <em>disable_preemption</em> property is set for this queue
|
||||||
* @return true if <em>disable_preemption</em> is set, false if not
|
* @return true if <em>disable_preemption</em> is set, false if not
|
||||||
*/
|
*/
|
||||||
public boolean getPreemptionDisabled();
|
public boolean getPreemptionDisabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get QueueCapacities of this queue
|
||||||
|
* @return queueCapacities
|
||||||
|
*/
|
||||||
|
public QueueCapacities getQueueCapacities();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get ResourceUsage of this queue
|
||||||
|
* @return resourceUsage
|
||||||
|
*/
|
||||||
|
public ResourceUsage getQueueResourceUsage();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,14 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
|
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Set;
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.yarn.api.records.Resource;
|
import org.apache.hadoop.yarn.api.records.Resource;
|
||||||
|
import org.apache.hadoop.yarn.nodelabels.CommonNodeLabelsManager;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager;
|
||||||
import org.apache.hadoop.yarn.server.utils.Lock;
|
import org.apache.hadoop.yarn.server.utils.Lock;
|
||||||
import org.apache.hadoop.yarn.util.resource.ResourceCalculator;
|
import org.apache.hadoop.yarn.util.resource.ResourceCalculator;
|
||||||
import org.apache.hadoop.yarn.util.resource.Resources;
|
import org.apache.hadoop.yarn.util.resource.Resources;
|
||||||
|
@ -34,6 +35,9 @@ class CSQueueUtils {
|
||||||
|
|
||||||
final static float EPSILON = 0.0001f;
|
final static float EPSILON = 0.0001f;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used only by tests
|
||||||
|
*/
|
||||||
public static void checkMaxCapacity(String queueName,
|
public static void checkMaxCapacity(String queueName,
|
||||||
float capacity, float maximumCapacity) {
|
float capacity, float maximumCapacity) {
|
||||||
if (maximumCapacity < 0.0f || maximumCapacity > 1.0f) {
|
if (maximumCapacity < 0.0f || maximumCapacity > 1.0f) {
|
||||||
|
@ -43,6 +47,9 @@ class CSQueueUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used only by tests
|
||||||
|
*/
|
||||||
public static void checkAbsoluteCapacity(String queueName,
|
public static void checkAbsoluteCapacity(String queueName,
|
||||||
float absCapacity, float absMaxCapacity) {
|
float absCapacity, float absMaxCapacity) {
|
||||||
if (absMaxCapacity < (absCapacity - EPSILON)) {
|
if (absMaxCapacity < (absCapacity - EPSILON)) {
|
||||||
|
@ -53,19 +60,33 @@ class CSQueueUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkAbsoluteCapacitiesByLabel(String queueName,
|
/**
|
||||||
Map<String, Float> absCapacities,
|
* Check sanity of capacities:
|
||||||
Map<String, Float> absMaximumCapacities) {
|
* - capacity <= maxCapacity
|
||||||
for (Entry<String, Float> entry : absCapacities.entrySet()) {
|
* - absCapacity <= absMaximumCapacity
|
||||||
String label = entry.getKey();
|
*/
|
||||||
float absCapacity = entry.getValue();
|
private static void capacitiesSanityCheck(String queueName,
|
||||||
float absMaxCapacity = absMaximumCapacities.get(label);
|
QueueCapacities queueCapacities) {
|
||||||
if (absMaxCapacity < (absCapacity - EPSILON)) {
|
for (String label : queueCapacities.getExistingNodeLabels()) {
|
||||||
throw new IllegalArgumentException("Illegal call to setMaxCapacity. "
|
float capacity = queueCapacities.getCapacity(label);
|
||||||
+ "Queue '" + queueName + "' has " + "an absolute capacity ("
|
float maximumCapacity = queueCapacities.getMaximumCapacity(label);
|
||||||
+ absCapacity + ") greater than "
|
if (capacity > maximumCapacity) {
|
||||||
+ "its absolute maximumCapacity (" + absMaxCapacity + ") of label="
|
throw new IllegalArgumentException("Illegal queue capacity setting, "
|
||||||
+ label);
|
+ "(capacity=" + capacity + ") > (maximum-capacity="
|
||||||
|
+ maximumCapacity + "). When label=[" + label + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actually, this may not needed since we have verified capacity <=
|
||||||
|
// maximumCapacity. And the way we compute absolute capacity (abs(x) =
|
||||||
|
// cap(x) * cap(x.parent) * ...) is a monotone increasing function. But
|
||||||
|
// just keep it here to make sure our compute abs capacity method works
|
||||||
|
// correctly.
|
||||||
|
float absCapacity = queueCapacities.getAbsoluteCapacity(label);
|
||||||
|
float absMaxCapacity = queueCapacities.getAbsoluteMaximumCapacity(label);
|
||||||
|
if (absCapacity > absMaxCapacity) {
|
||||||
|
throw new IllegalArgumentException("Illegal queue capacity setting, "
|
||||||
|
+ "(abs-capacity=" + absCapacity + ") > (abs-maximum-capacity="
|
||||||
|
+ absMaxCapacity + "). When label=[" + label + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,37 +98,94 @@ class CSQueueUtils {
|
||||||
return (parentAbsMaxCapacity * maximumCapacity);
|
return (parentAbsMaxCapacity * maximumCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, Float> computeAbsoluteCapacityByNodeLabels(
|
/**
|
||||||
Map<String, Float> nodeLabelToCapacities, CSQueue parent) {
|
* This method intends to be used by ReservationQueue, ReservationQueue will
|
||||||
if (parent == null) {
|
* not appear in configuration file, so we shouldn't do load capacities
|
||||||
return nodeLabelToCapacities;
|
* settings in configuration for reservation queue.
|
||||||
}
|
*/
|
||||||
|
public static void updateAndCheckCapacitiesByLabel(String queuePath,
|
||||||
Map<String, Float> absoluteCapacityByNodeLabels =
|
QueueCapacities queueCapacities, QueueCapacities parentQueueCapacities) {
|
||||||
new HashMap<String, Float>();
|
updateAbsoluteCapacitiesByNodeLabels(queueCapacities, parentQueueCapacities);
|
||||||
for (Entry<String, Float> entry : nodeLabelToCapacities.entrySet()) {
|
|
||||||
String label = entry.getKey();
|
capacitiesSanityCheck(queuePath, queueCapacities);
|
||||||
float capacity = entry.getValue();
|
}
|
||||||
absoluteCapacityByNodeLabels.put(label,
|
|
||||||
capacity * parent.getAbsoluteCapacityByNodeLabel(label));
|
/**
|
||||||
}
|
* Do following steps for capacities
|
||||||
return absoluteCapacityByNodeLabels;
|
* - Load capacities from configuration
|
||||||
|
* - Update absolute capacities for new capacities
|
||||||
|
* - Check if capacities/absolute-capacities legal
|
||||||
|
*/
|
||||||
|
public static void loadUpdateAndCheckCapacities(String queuePath,
|
||||||
|
Set<String> accessibleLabels, CapacitySchedulerConfiguration csConf,
|
||||||
|
QueueCapacities queueCapacities, QueueCapacities parentQueueCapacities,
|
||||||
|
RMNodeLabelsManager nlm) {
|
||||||
|
loadCapacitiesByLabelsFromConf(queuePath, accessibleLabels, nlm,
|
||||||
|
queueCapacities, csConf);
|
||||||
|
|
||||||
|
updateAbsoluteCapacitiesByNodeLabels(queueCapacities, parentQueueCapacities);
|
||||||
|
|
||||||
|
capacitiesSanityCheck(queuePath, queueCapacities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, Float> computeAbsoluteMaxCapacityByNodeLabels(
|
// Considered NO_LABEL, ANY and null cases
|
||||||
Map<String, Float> maximumNodeLabelToCapacities, CSQueue parent) {
|
private static Set<String> normalizeAccessibleNodeLabels(Set<String> labels,
|
||||||
if (parent == null) {
|
RMNodeLabelsManager mgr) {
|
||||||
return maximumNodeLabelToCapacities;
|
Set<String> accessibleLabels = new HashSet<String>();
|
||||||
|
if (labels != null) {
|
||||||
|
accessibleLabels.addAll(labels);
|
||||||
}
|
}
|
||||||
Map<String, Float> absoluteMaxCapacityByNodeLabels =
|
if (accessibleLabels.contains(CommonNodeLabelsManager.ANY)) {
|
||||||
new HashMap<String, Float>();
|
accessibleLabels.addAll(mgr.getClusterNodeLabels());
|
||||||
for (Entry<String, Float> entry : maximumNodeLabelToCapacities.entrySet()) {
|
}
|
||||||
String label = entry.getKey();
|
accessibleLabels.add(CommonNodeLabelsManager.NO_LABEL);
|
||||||
float maxCapacity = entry.getValue();
|
|
||||||
absoluteMaxCapacityByNodeLabels.put(label,
|
return accessibleLabels;
|
||||||
maxCapacity * parent.getAbsoluteMaximumCapacityByNodeLabel(label));
|
}
|
||||||
|
|
||||||
|
private static void loadCapacitiesByLabelsFromConf(String queuePath,
|
||||||
|
Set<String> labels, RMNodeLabelsManager mgr,
|
||||||
|
QueueCapacities queueCapacities, CapacitySchedulerConfiguration csConf) {
|
||||||
|
queueCapacities.clearConfigurableFields();
|
||||||
|
labels = normalizeAccessibleNodeLabels(labels, mgr);
|
||||||
|
|
||||||
|
for (String label : labels) {
|
||||||
|
if (label.equals(CommonNodeLabelsManager.NO_LABEL)) {
|
||||||
|
queueCapacities.setCapacity(CommonNodeLabelsManager.NO_LABEL,
|
||||||
|
csConf.getNonLabeledQueueCapacity(queuePath) / 100);
|
||||||
|
queueCapacities.setMaximumCapacity(CommonNodeLabelsManager.NO_LABEL,
|
||||||
|
csConf.getNonLabeledQueueMaximumCapacity(queuePath) / 100);
|
||||||
|
} else {
|
||||||
|
queueCapacities.setCapacity(label,
|
||||||
|
csConf.getLabeledQueueCapacity(queuePath, label) / 100);
|
||||||
|
queueCapacities.setMaximumCapacity(label,
|
||||||
|
csConf.getLabeledQueueMaximumCapacity(queuePath, label) / 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set absolute capacities for {capacity, maximum-capacity}
|
||||||
|
private static void updateAbsoluteCapacitiesByNodeLabels(
|
||||||
|
QueueCapacities queueCapacities, QueueCapacities parentQueueCapacities) {
|
||||||
|
for (String label : queueCapacities.getExistingNodeLabels()) {
|
||||||
|
float capacity = queueCapacities.getCapacity(label);
|
||||||
|
if (capacity > 0f) {
|
||||||
|
queueCapacities.setAbsoluteCapacity(
|
||||||
|
label,
|
||||||
|
capacity
|
||||||
|
* (parentQueueCapacities == null ? 1 : parentQueueCapacities
|
||||||
|
.getAbsoluteCapacity(label)));
|
||||||
|
}
|
||||||
|
|
||||||
|
float maxCapacity = queueCapacities.getMaximumCapacity(label);
|
||||||
|
if (maxCapacity > 0f) {
|
||||||
|
queueCapacities.setAbsoluteMaximumCapacity(
|
||||||
|
label,
|
||||||
|
maxCapacity
|
||||||
|
* (parentQueueCapacities == null ? 1 : parentQueueCapacities
|
||||||
|
.getAbsoluteMaximumCapacity(label)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return absoluteMaxCapacityByNodeLabels;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Lock(CSQueue.class)
|
@Lock(CSQueue.class)
|
||||||
|
|
|
@ -278,6 +278,9 @@ public class CapacitySchedulerConfiguration extends ReservationSchedulerConfigur
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getNodeLabelPrefix(String queue, String label) {
|
private String getNodeLabelPrefix(String queue, String label) {
|
||||||
|
if (label.equals(CommonNodeLabelsManager.NO_LABEL)) {
|
||||||
|
return getQueuePrefix(queue);
|
||||||
|
}
|
||||||
return getQueuePrefix(queue) + ACCESSIBLE_NODE_LABELS + DOT + label + DOT;
|
return getQueuePrefix(queue) + ACCESSIBLE_NODE_LABELS + DOT + label + DOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +319,7 @@ public class CapacitySchedulerConfiguration extends ReservationSchedulerConfigur
|
||||||
getMaximumApplicationMasterResourcePercent());
|
getMaximumApplicationMasterResourcePercent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getCapacity(String queue) {
|
public float getNonLabeledQueueCapacity(String queue) {
|
||||||
float capacity = queue.equals("root") ? 100.0f : getFloat(
|
float capacity = queue.equals("root") ? 100.0f : getFloat(
|
||||||
getQueuePrefix(queue) + CAPACITY, UNDEFINED);
|
getQueuePrefix(queue) + CAPACITY, UNDEFINED);
|
||||||
if (capacity < MINIMUM_CAPACITY_VALUE || capacity > MAXIMUM_CAPACITY_VALUE) {
|
if (capacity < MINIMUM_CAPACITY_VALUE || capacity > MAXIMUM_CAPACITY_VALUE) {
|
||||||
|
@ -338,7 +341,7 @@ public class CapacitySchedulerConfiguration extends ReservationSchedulerConfigur
|
||||||
", capacity=" + capacity);
|
", capacity=" + capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getMaximumCapacity(String queue) {
|
public float getNonLabeledQueueMaximumCapacity(String queue) {
|
||||||
float maxCapacity = getFloat(getQueuePrefix(queue) + MAXIMUM_CAPACITY,
|
float maxCapacity = getFloat(getQueuePrefix(queue) + MAXIMUM_CAPACITY,
|
||||||
MAXIMUM_CAPACITY_VALUE);
|
MAXIMUM_CAPACITY_VALUE);
|
||||||
maxCapacity = (maxCapacity == DEFAULT_MAXIMUM_CAPACITY_VALUE) ?
|
maxCapacity = (maxCapacity == DEFAULT_MAXIMUM_CAPACITY_VALUE) ?
|
||||||
|
@ -442,57 +445,29 @@ public class CapacitySchedulerConfiguration extends ReservationSchedulerConfigur
|
||||||
return Collections.unmodifiableSet(set);
|
return Collections.unmodifiableSet(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Float> getNodeLabelCapacities(String queue,
|
private float internalGetLabeledQueueCapacity(String queue, String label, String suffix,
|
||||||
Set<String> labels, RMNodeLabelsManager mgr) {
|
float defaultValue) {
|
||||||
Map<String, Float> nodeLabelCapacities = new HashMap<String, Float>();
|
String capacityPropertyName = getNodeLabelPrefix(queue, label) + suffix;
|
||||||
|
float capacity = getFloat(capacityPropertyName, defaultValue);
|
||||||
if (labels == null) {
|
if (capacity < MINIMUM_CAPACITY_VALUE
|
||||||
return nodeLabelCapacities;
|
|| capacity > MAXIMUM_CAPACITY_VALUE) {
|
||||||
|
throw new IllegalArgumentException("Illegal capacity of " + capacity
|
||||||
|
+ " for node-label=" + label + " in queue=" + queue
|
||||||
|
+ ", valid capacity should in range of [0, 100].");
|
||||||
}
|
}
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
for (String label : labels.contains(CommonNodeLabelsManager.ANY) ? mgr
|
LOG.debug("CSConf - getCapacityOfLabel: prefix="
|
||||||
.getClusterNodeLabels() : labels) {
|
+ getNodeLabelPrefix(queue, label) + ", capacity=" + capacity);
|
||||||
String capacityPropertyName = getNodeLabelPrefix(queue, label) + CAPACITY;
|
|
||||||
float capacity = getFloat(capacityPropertyName, 0f);
|
|
||||||
if (capacity < MINIMUM_CAPACITY_VALUE
|
|
||||||
|| capacity > MAXIMUM_CAPACITY_VALUE) {
|
|
||||||
throw new IllegalArgumentException("Illegal capacity of " + capacity
|
|
||||||
+ " for node-label=" + label + " in queue=" + queue
|
|
||||||
+ ", valid capacity should in range of [0, 100].");
|
|
||||||
}
|
|
||||||
if (LOG.isDebugEnabled()) {
|
|
||||||
LOG.debug("CSConf - getCapacityOfLabel: prefix="
|
|
||||||
+ getNodeLabelPrefix(queue, label) + ", capacity=" + capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeLabelCapacities.put(label, capacity / 100f);
|
|
||||||
}
|
}
|
||||||
return nodeLabelCapacities;
|
return capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Float> getMaximumNodeLabelCapacities(String queue,
|
public float getLabeledQueueCapacity(String queue, String label) {
|
||||||
Set<String> labels, RMNodeLabelsManager mgr) {
|
return internalGetLabeledQueueCapacity(queue, label, CAPACITY, 0f);
|
||||||
Map<String, Float> maximumNodeLabelCapacities = new HashMap<String, Float>();
|
}
|
||||||
if (labels == null) {
|
|
||||||
return maximumNodeLabelCapacities;
|
public float getLabeledQueueMaximumCapacity(String queue, String label) {
|
||||||
}
|
return internalGetLabeledQueueCapacity(queue, label, MAXIMUM_CAPACITY, 100f);
|
||||||
|
|
||||||
for (String label : labels.contains(CommonNodeLabelsManager.ANY) ? mgr
|
|
||||||
.getClusterNodeLabels() : labels) {
|
|
||||||
float maxCapacity =
|
|
||||||
getFloat(getNodeLabelPrefix(queue, label) + MAXIMUM_CAPACITY,
|
|
||||||
100f);
|
|
||||||
if (maxCapacity < MINIMUM_CAPACITY_VALUE
|
|
||||||
|| maxCapacity > MAXIMUM_CAPACITY_VALUE) {
|
|
||||||
throw new IllegalArgumentException("Illegal " + "capacity of "
|
|
||||||
+ maxCapacity + " for label=" + label + " in queue=" + queue);
|
|
||||||
}
|
|
||||||
LOG.debug("CSConf - getCapacityOfLabel: prefix="
|
|
||||||
+ getNodeLabelPrefix(queue, label) + ", capacity=" + maxCapacity);
|
|
||||||
|
|
||||||
maximumNodeLabelCapacities.put(label, maxCapacity / 100f);
|
|
||||||
}
|
|
||||||
return maximumNodeLabelCapacities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDefaultNodeLabelExpression(String queue) {
|
public String getDefaultNodeLabelExpression(String queue) {
|
||||||
|
|
|
@ -122,49 +122,7 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
super(cs, queueName, parent, old);
|
super(cs, queueName, parent, old);
|
||||||
this.scheduler = cs;
|
this.scheduler = cs;
|
||||||
|
|
||||||
this.activeUsersManager = new ActiveUsersManager(metrics);
|
this.activeUsersManager = new ActiveUsersManager(metrics);
|
||||||
this.minimumAllocationFactor =
|
|
||||||
Resources.ratio(resourceCalculator,
|
|
||||||
Resources.subtract(maximumAllocation, minimumAllocation),
|
|
||||||
maximumAllocation);
|
|
||||||
|
|
||||||
float capacity = getCapacityFromConf();
|
|
||||||
float absoluteCapacity = parent.getAbsoluteCapacity() * capacity;
|
|
||||||
|
|
||||||
float maximumCapacity =
|
|
||||||
(float)cs.getConfiguration().getMaximumCapacity(getQueuePath()) / 100;
|
|
||||||
float absoluteMaxCapacity =
|
|
||||||
CSQueueUtils.computeAbsoluteMaximumCapacity(maximumCapacity, parent);
|
|
||||||
|
|
||||||
int userLimit = cs.getConfiguration().getUserLimit(getQueuePath());
|
|
||||||
float userLimitFactor =
|
|
||||||
cs.getConfiguration().getUserLimitFactor(getQueuePath());
|
|
||||||
|
|
||||||
int maxApplications =
|
|
||||||
cs.getConfiguration().getMaximumApplicationsPerQueue(getQueuePath());
|
|
||||||
if (maxApplications < 0) {
|
|
||||||
int maxSystemApps = cs.getConfiguration().getMaximumSystemApplications();
|
|
||||||
maxApplications = (int)(maxSystemApps * absoluteCapacity);
|
|
||||||
}
|
|
||||||
maxApplicationsPerUser =
|
|
||||||
(int)(maxApplications * (userLimit / 100.0f) * userLimitFactor);
|
|
||||||
|
|
||||||
float maxAMResourcePerQueuePercent = cs.getConfiguration()
|
|
||||||
.getMaximumApplicationMasterResourcePerQueuePercent(getQueuePath());
|
|
||||||
|
|
||||||
QueueState state = cs.getConfiguration().getState(getQueuePath());
|
|
||||||
|
|
||||||
Map<AccessType, AccessControlList> acls =
|
|
||||||
cs.getConfiguration().getAcls(getQueuePath());
|
|
||||||
|
|
||||||
setupQueueConfigs(cs.getClusterResource(), capacity, absoluteCapacity,
|
|
||||||
maximumCapacity, absoluteMaxCapacity, userLimit, userLimitFactor,
|
|
||||||
maxApplications, maxAMResourcePerQueuePercent, maxApplicationsPerUser,
|
|
||||||
state, acls, cs.getConfiguration().getNodeLocalityDelay(), accessibleLabels,
|
|
||||||
defaultLabelExpression, this.capacitiyByNodeLabels,
|
|
||||||
this.maxCapacityByNodeLabels,
|
|
||||||
cs.getConfiguration().getReservationContinueLook(),
|
|
||||||
cs.getConfiguration().getMaximumAllocationPerQueue(getQueuePath()));
|
|
||||||
|
|
||||||
if(LOG.isDebugEnabled()) {
|
if(LOG.isDebugEnabled()) {
|
||||||
LOG.debug("LeafQueue:" + " name=" + queueName
|
LOG.debug("LeafQueue:" + " name=" + queueName
|
||||||
|
@ -176,35 +134,13 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
this.pendingApplications =
|
this.pendingApplications =
|
||||||
new TreeSet<FiCaSchedulerApp>(applicationComparator);
|
new TreeSet<FiCaSchedulerApp>(applicationComparator);
|
||||||
this.activeApplications = new TreeSet<FiCaSchedulerApp>(applicationComparator);
|
this.activeApplications = new TreeSet<FiCaSchedulerApp>(applicationComparator);
|
||||||
}
|
|
||||||
|
setupQueueConfigs(cs.getClusterResource());
|
||||||
// externalizing in method, to allow overriding
|
|
||||||
protected float getCapacityFromConf() {
|
|
||||||
return (float)scheduler.getConfiguration().getCapacity(getQueuePath()) / 100;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected synchronized void setupQueueConfigs(
|
protected synchronized void setupQueueConfigs(Resource clusterResource)
|
||||||
Resource clusterResource,
|
throws IOException {
|
||||||
float capacity, float absoluteCapacity,
|
super.setupQueueConfigs(clusterResource);
|
||||||
float maximumCapacity, float absoluteMaxCapacity,
|
|
||||||
int userLimit, float userLimitFactor,
|
|
||||||
int maxApplications, float maxAMResourcePerQueuePercent,
|
|
||||||
int maxApplicationsPerUser, QueueState state,
|
|
||||||
Map<AccessType, AccessControlList> acls, int nodeLocalityDelay,
|
|
||||||
Set<String> labels, String defaultLabelExpression,
|
|
||||||
Map<String, Float> capacitieByLabel,
|
|
||||||
Map<String, Float> maximumCapacitiesByLabel,
|
|
||||||
boolean revervationContinueLooking,
|
|
||||||
Resource maxAllocation) throws IOException {
|
|
||||||
super.setupQueueConfigs(clusterResource, capacity, absoluteCapacity,
|
|
||||||
maximumCapacity, absoluteMaxCapacity, state, acls, labels,
|
|
||||||
defaultLabelExpression, capacitieByLabel, maximumCapacitiesByLabel,
|
|
||||||
revervationContinueLooking, maxAllocation);
|
|
||||||
// Sanity check
|
|
||||||
CSQueueUtils.checkMaxCapacity(getQueueName(), capacity, maximumCapacity);
|
|
||||||
float absCapacity = getParent().getAbsoluteCapacity() * capacity;
|
|
||||||
CSQueueUtils.checkAbsoluteCapacity(getQueueName(), absCapacity,
|
|
||||||
absoluteMaxCapacity);
|
|
||||||
|
|
||||||
this.lastClusterResource = clusterResource;
|
this.lastClusterResource = clusterResource;
|
||||||
updateAbsoluteCapacityResource(clusterResource);
|
updateAbsoluteCapacityResource(clusterResource);
|
||||||
|
@ -214,16 +150,24 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
// and all queues may not be realized yet, we'll use (optimistic)
|
// and all queues may not be realized yet, we'll use (optimistic)
|
||||||
// absoluteMaxCapacity (it will be replaced with the more accurate
|
// absoluteMaxCapacity (it will be replaced with the more accurate
|
||||||
// absoluteMaxAvailCapacity during headroom/userlimit/allocation events)
|
// absoluteMaxAvailCapacity during headroom/userlimit/allocation events)
|
||||||
updateHeadroomInfo(clusterResource, absoluteMaxCapacity);
|
updateHeadroomInfo(clusterResource,
|
||||||
|
queueCapacities.getAbsoluteMaximumCapacity());
|
||||||
|
|
||||||
this.absoluteCapacity = absCapacity;
|
CapacitySchedulerConfiguration conf = csContext.getConfiguration();
|
||||||
|
userLimit = conf.getUserLimit(getQueuePath());
|
||||||
|
userLimitFactor = conf.getUserLimitFactor(getQueuePath());
|
||||||
|
|
||||||
this.userLimit = userLimit;
|
maxApplications = conf.getMaximumApplicationsPerQueue(getQueuePath());
|
||||||
this.userLimitFactor = userLimitFactor;
|
if (maxApplications < 0) {
|
||||||
|
int maxSystemApps = conf.getMaximumSystemApplications();
|
||||||
this.maxApplications = maxApplications;
|
maxApplications =
|
||||||
this.maxAMResourcePerQueuePercent = maxAMResourcePerQueuePercent;
|
(int) (maxSystemApps * queueCapacities.getAbsoluteCapacity());
|
||||||
this.maxApplicationsPerUser = maxApplicationsPerUser;
|
}
|
||||||
|
maxApplicationsPerUser =
|
||||||
|
(int)(maxApplications * (userLimit / 100.0f) * userLimitFactor);
|
||||||
|
|
||||||
|
maxAMResourcePerQueuePercent =
|
||||||
|
conf.getMaximumApplicationMasterResourcePerQueuePercent(getQueuePath());
|
||||||
|
|
||||||
if (!SchedulerUtils.checkQueueLabelExpression(this.accessibleLabels,
|
if (!SchedulerUtils.checkQueueLabelExpression(this.accessibleLabels,
|
||||||
this.defaultLabelExpression)) {
|
this.defaultLabelExpression)) {
|
||||||
|
@ -239,7 +183,7 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
getAccessibleNodeLabels().iterator(), ',')));
|
getAccessibleNodeLabels().iterator(), ',')));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.nodeLocalityDelay = nodeLocalityDelay;
|
nodeLocalityDelay = conf.getNodeLocalityDelay();
|
||||||
|
|
||||||
// re-init this since max allocation could have changed
|
// re-init this since max allocation could have changed
|
||||||
this.minimumAllocationFactor =
|
this.minimumAllocationFactor =
|
||||||
|
@ -253,21 +197,21 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder labelStrBuilder = new StringBuilder();
|
StringBuilder labelStrBuilder = new StringBuilder();
|
||||||
if (labels != null) {
|
if (accessibleLabels != null) {
|
||||||
for (String s : labels) {
|
for (String s : accessibleLabels) {
|
||||||
labelStrBuilder.append(s);
|
labelStrBuilder.append(s);
|
||||||
labelStrBuilder.append(",");
|
labelStrBuilder.append(",");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.info("Initializing " + queueName + "\n" +
|
LOG.info("Initializing " + queueName + "\n" +
|
||||||
"capacity = " + capacity +
|
"capacity = " + queueCapacities.getCapacity() +
|
||||||
" [= (float) configuredCapacity / 100 ]" + "\n" +
|
" [= (float) configuredCapacity / 100 ]" + "\n" +
|
||||||
"asboluteCapacity = " + absoluteCapacity +
|
"asboluteCapacity = " + queueCapacities.getAbsoluteCapacity() +
|
||||||
" [= parentAbsoluteCapacity * capacity ]" + "\n" +
|
" [= parentAbsoluteCapacity * capacity ]" + "\n" +
|
||||||
"maxCapacity = " + maximumCapacity +
|
"maxCapacity = " + queueCapacities.getMaximumCapacity() +
|
||||||
" [= configuredMaxCapacity ]" + "\n" +
|
" [= configuredMaxCapacity ]" + "\n" +
|
||||||
"absoluteMaxCapacity = " + absoluteMaxCapacity +
|
"absoluteMaxCapacity = " + queueCapacities.getAbsoluteMaximumCapacity() +
|
||||||
" [= 1.0 maximumCapacity undefined, " +
|
" [= 1.0 maximumCapacity undefined, " +
|
||||||
"(parentAbsoluteMaxCapacity * maximumCapacity) / 100 otherwise ]" +
|
"(parentAbsoluteMaxCapacity * maximumCapacity) / 100 otherwise ]" +
|
||||||
"\n" +
|
"\n" +
|
||||||
|
@ -282,7 +226,7 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
"maxApplicationsPerUser = " + maxApplicationsPerUser +
|
"maxApplicationsPerUser = " + maxApplicationsPerUser +
|
||||||
" [= (int)(maxApplications * (userLimit / 100.0f) * " +
|
" [= (int)(maxApplications * (userLimit / 100.0f) * " +
|
||||||
"userLimitFactor) ]" + "\n" +
|
"userLimitFactor) ]" + "\n" +
|
||||||
"usedCapacity = " + usedCapacity +
|
"usedCapacity = " + queueCapacities.getUsedCapacity() +
|
||||||
" [= usedResourcesMemory / " +
|
" [= usedResourcesMemory / " +
|
||||||
"(clusterResourceMemory * absoluteCapacity)]" + "\n" +
|
"(clusterResourceMemory * absoluteCapacity)]" + "\n" +
|
||||||
"absoluteUsedCapacity = " + absoluteUsedCapacity +
|
"absoluteUsedCapacity = " + absoluteUsedCapacity +
|
||||||
|
@ -441,8 +385,8 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return queueName + ": " +
|
return queueName + ": " +
|
||||||
"capacity=" + capacity + ", " +
|
"capacity=" + queueCapacities.getCapacity() + ", " +
|
||||||
"absoluteCapacity=" + absoluteCapacity + ", " +
|
"absoluteCapacity=" + queueCapacities.getAbsoluteCapacity() + ", " +
|
||||||
"usedResources=" + queueUsage.getUsed() + ", " +
|
"usedResources=" + queueUsage.getUsed() + ", " +
|
||||||
"usedCapacity=" + getUsedCapacity() + ", " +
|
"usedCapacity=" + getUsedCapacity() + ", " +
|
||||||
"absoluteUsedCapacity=" + getAbsoluteUsedCapacity() + ", " +
|
"absoluteUsedCapacity=" + getAbsoluteUsedCapacity() + ", " +
|
||||||
|
@ -505,23 +449,7 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
+ ", trying to set it to: " + newMax);
|
+ ", trying to set it to: " + newMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
setupQueueConfigs(
|
setupQueueConfigs(clusterResource);
|
||||||
clusterResource,
|
|
||||||
newlyParsedLeafQueue.capacity, newlyParsedLeafQueue.absoluteCapacity,
|
|
||||||
newlyParsedLeafQueue.maximumCapacity,
|
|
||||||
newlyParsedLeafQueue.absoluteMaxCapacity,
|
|
||||||
newlyParsedLeafQueue.userLimit, newlyParsedLeafQueue.userLimitFactor,
|
|
||||||
newlyParsedLeafQueue.maxApplications,
|
|
||||||
newlyParsedLeafQueue.maxAMResourcePerQueuePercent,
|
|
||||||
newlyParsedLeafQueue.getMaxApplicationsPerUser(),
|
|
||||||
newlyParsedLeafQueue.state, newlyParsedLeafQueue.acls,
|
|
||||||
newlyParsedLeafQueue.getNodeLocalityDelay(),
|
|
||||||
newlyParsedLeafQueue.accessibleLabels,
|
|
||||||
newlyParsedLeafQueue.defaultLabelExpression,
|
|
||||||
newlyParsedLeafQueue.capacitiyByNodeLabels,
|
|
||||||
newlyParsedLeafQueue.maxCapacityByNodeLabels,
|
|
||||||
newlyParsedLeafQueue.reservationsContinueLooking,
|
|
||||||
newlyParsedLeafQueue.getMaximumAllocation());
|
|
||||||
|
|
||||||
// queue metrics are updated, more resource may be available
|
// queue metrics are updated, more resource may be available
|
||||||
// activate the pending applications if possible
|
// activate the pending applications if possible
|
||||||
|
@ -1034,7 +962,8 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
application.getCurrentReservation()),
|
application.getCurrentReservation()),
|
||||||
labelManager.getResourceByLabel(label, clusterResource));
|
labelManager.getResourceByLabel(label, clusterResource));
|
||||||
|
|
||||||
if (potentialNewWithoutReservedCapacity <= absoluteMaxCapacity) {
|
if (potentialNewWithoutReservedCapacity <= queueCapacities
|
||||||
|
.getAbsoluteMaximumCapacity()) {
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("try to use reserved: "
|
LOG.debug("try to use reserved: "
|
||||||
+ getQueueName()
|
+ getQueueName()
|
||||||
|
@ -1048,8 +977,9 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
+ Resources.divide(resourceCalculator, clusterResource,
|
+ Resources.divide(resourceCalculator, clusterResource,
|
||||||
queueUsage.getUsed(), clusterResource) + " required " + required
|
queueUsage.getUsed(), clusterResource) + " required " + required
|
||||||
+ " potentialNewWithoutReservedCapacity: "
|
+ " potentialNewWithoutReservedCapacity: "
|
||||||
+ potentialNewWithoutReservedCapacity + " ( " + " max-capacity: "
|
+ potentialNewWithoutReservedCapacity + " ( "
|
||||||
+ absoluteMaxCapacity + ")");
|
+ " max-capacity: "
|
||||||
|
+ queueCapacities.getAbsoluteMaximumCapacity() + ")");
|
||||||
}
|
}
|
||||||
// we could potentially use this node instead of reserved node
|
// we could potentially use this node instead of reserved node
|
||||||
return true;
|
return true;
|
||||||
|
@ -1058,7 +988,8 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
|
|
||||||
// Otherwise, if any of the label of this node beyond queue limit, we
|
// Otherwise, if any of the label of this node beyond queue limit, we
|
||||||
// cannot allocate on this node. Consider a small epsilon here.
|
// cannot allocate on this node. Consider a small epsilon here.
|
||||||
if (potentialNewCapacity > getAbsoluteMaximumCapacityByNodeLabel(label) + 1e-4) {
|
if (potentialNewCapacity > queueCapacities
|
||||||
|
.getAbsoluteMaximumCapacity(label) + 1e-4) {
|
||||||
canAssign = false;
|
canAssign = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1073,7 +1004,8 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
queueUsage.getUsed(label),
|
queueUsage.getUsed(label),
|
||||||
labelManager.getResourceByLabel(label, clusterResource))
|
labelManager.getResourceByLabel(label, clusterResource))
|
||||||
+ " potentialNewCapacity: " + potentialNewCapacity + " ( "
|
+ " potentialNewCapacity: " + potentialNewCapacity + " ( "
|
||||||
+ " max-capacity: " + absoluteMaxCapacity + ")");
|
+ " max-capacity: " + queueCapacities.getAbsoluteMaximumCapacity()
|
||||||
|
+ ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1162,7 +1094,7 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
Resources.multiplyAndNormalizeUp(resourceCalculator,
|
Resources.multiplyAndNormalizeUp(resourceCalculator,
|
||||||
labelManager.getResourceByLabel(firstLabel,
|
labelManager.getResourceByLabel(firstLabel,
|
||||||
clusterResource),
|
clusterResource),
|
||||||
getAbsoluteCapacityByNodeLabel(firstLabel),
|
queueCapacities.getAbsoluteCapacity(firstLabel),
|
||||||
minimumAllocation));
|
minimumAllocation));
|
||||||
} else {
|
} else {
|
||||||
// else there's no label on request, just to use absolute capacity as
|
// else there's no label on request, just to use absolute capacity as
|
||||||
|
@ -1170,7 +1102,7 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
queueCapacity =
|
queueCapacity =
|
||||||
Resources.multiplyAndNormalizeUp(resourceCalculator, labelManager
|
Resources.multiplyAndNormalizeUp(resourceCalculator, labelManager
|
||||||
.getResourceByLabel(CommonNodeLabelsManager.NO_LABEL, clusterResource),
|
.getResourceByLabel(CommonNodeLabelsManager.NO_LABEL, clusterResource),
|
||||||
absoluteCapacity, minimumAllocation);
|
queueCapacities.getAbsoluteCapacity(), minimumAllocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow progress for queues with miniscule capacity
|
// Allow progress for queues with miniscule capacity
|
||||||
|
@ -1815,12 +1747,9 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAbsoluteCapacityResource(Resource clusterResource) {
|
private void updateAbsoluteCapacityResource(Resource clusterResource) {
|
||||||
|
absoluteCapacityResource =
|
||||||
absoluteCapacityResource = Resources.multiplyAndNormalizeUp(
|
Resources.multiplyAndNormalizeUp(resourceCalculator, clusterResource,
|
||||||
resourceCalculator,
|
queueCapacities.getAbsoluteCapacity(), minimumAllocation);
|
||||||
clusterResource,
|
|
||||||
absoluteCapacity, minimumAllocation);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1831,7 +1760,8 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
// Update headroom info based on new cluster resource value
|
// Update headroom info based on new cluster resource value
|
||||||
// absoluteMaxCapacity now, will be replaced with absoluteMaxAvailCapacity
|
// absoluteMaxCapacity now, will be replaced with absoluteMaxAvailCapacity
|
||||||
// during allocation
|
// during allocation
|
||||||
updateHeadroomInfo(clusterResource, absoluteMaxCapacity);
|
updateHeadroomInfo(clusterResource,
|
||||||
|
queueCapacities.getAbsoluteMaximumCapacity());
|
||||||
|
|
||||||
// Update metrics
|
// Update metrics
|
||||||
CSQueueUtils.updateQueueStatistics(
|
CSQueueUtils.updateQueueStatistics(
|
||||||
|
@ -2004,35 +1934,13 @@ public class LeafQueue extends AbstractCSQueue {
|
||||||
getParent().detachContainer(clusterResource, application, rmContainer);
|
getParent().detachContainer(clusterResource, application, rmContainer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getAbsActualCapacity() {
|
|
||||||
//? Is this actually used by anything at present?
|
|
||||||
// There is a findbugs warning -re lastClusterResource (now excluded),
|
|
||||||
// when this is used, verify that the access is mt correct and remove
|
|
||||||
// the findbugs exclusion if possible
|
|
||||||
if (Resources.lessThanOrEqual(resourceCalculator, lastClusterResource,
|
|
||||||
lastClusterResource, Resources.none())) {
|
|
||||||
return absoluteCapacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
Resource resourceRespectLabels =
|
|
||||||
labelManager == null ? lastClusterResource : labelManager
|
|
||||||
.getQueueResource(queueName, accessibleLabels, lastClusterResource);
|
|
||||||
float absActualCapacity =
|
|
||||||
Resources.divide(resourceCalculator, lastClusterResource,
|
|
||||||
resourceRespectLabels, lastClusterResource);
|
|
||||||
|
|
||||||
return absActualCapacity > absoluteCapacity ? absoluteCapacity
|
|
||||||
: absActualCapacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCapacity(float capacity) {
|
public void setCapacity(float capacity) {
|
||||||
this.capacity = capacity;
|
queueCapacities.setCapacity(capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAbsoluteCapacity(float absoluteCapacity) {
|
public void setAbsoluteCapacity(float absoluteCapacity) {
|
||||||
this.absoluteCapacity = absoluteCapacity;
|
queueCapacities.setAbsoluteCapacity(absoluteCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMaxApplications(int maxApplications) {
|
public void setMaxApplications(int maxApplications) {
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class ParentQueue extends AbstractCSQueue {
|
||||||
|
|
||||||
this.rootQueue = (parent == null);
|
this.rootQueue = (parent == null);
|
||||||
|
|
||||||
float rawCapacity = cs.getConfiguration().getCapacity(getQueuePath());
|
float rawCapacity = cs.getConfiguration().getNonLabeledQueueCapacity(getQueuePath());
|
||||||
|
|
||||||
if (rootQueue &&
|
if (rootQueue &&
|
||||||
(rawCapacity != CapacitySchedulerConfiguration.MAXIMUM_CAPACITY_VALUE)) {
|
(rawCapacity != CapacitySchedulerConfiguration.MAXIMUM_CAPACITY_VALUE)) {
|
||||||
|
@ -95,46 +95,20 @@ public class ParentQueue extends AbstractCSQueue {
|
||||||
"capacity of " + rawCapacity + " for queue " + queueName +
|
"capacity of " + rawCapacity + " for queue " + queueName +
|
||||||
". Must be " + CapacitySchedulerConfiguration.MAXIMUM_CAPACITY_VALUE);
|
". Must be " + CapacitySchedulerConfiguration.MAXIMUM_CAPACITY_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
float capacity = (float) rawCapacity / 100;
|
|
||||||
float parentAbsoluteCapacity =
|
|
||||||
(rootQueue) ? 1.0f : parent.getAbsoluteCapacity();
|
|
||||||
float absoluteCapacity = parentAbsoluteCapacity * capacity;
|
|
||||||
|
|
||||||
float maximumCapacity =
|
|
||||||
(float) cs.getConfiguration().getMaximumCapacity(getQueuePath()) / 100;
|
|
||||||
float absoluteMaxCapacity =
|
|
||||||
CSQueueUtils.computeAbsoluteMaximumCapacity(maximumCapacity, parent);
|
|
||||||
|
|
||||||
QueueState state = cs.getConfiguration().getState(getQueuePath());
|
|
||||||
|
|
||||||
Map<AccessType, AccessControlList> acls =
|
|
||||||
cs.getConfiguration().getAcls(getQueuePath());
|
|
||||||
|
|
||||||
setupQueueConfigs(cs.getClusterResource(), capacity, absoluteCapacity,
|
|
||||||
maximumCapacity, absoluteMaxCapacity, state, acls, accessibleLabels,
|
|
||||||
defaultLabelExpression, capacitiyByNodeLabels, maxCapacityByNodeLabels,
|
|
||||||
cs.getConfiguration().getReservationContinueLook());
|
|
||||||
|
|
||||||
this.childQueues = new TreeSet<CSQueue>(queueComparator);
|
this.childQueues = new TreeSet<CSQueue>(queueComparator);
|
||||||
|
|
||||||
|
setupQueueConfigs(cs.getClusterResource());
|
||||||
|
|
||||||
LOG.info("Initialized parent-queue " + queueName +
|
LOG.info("Initialized parent-queue " + queueName +
|
||||||
" name=" + queueName +
|
" name=" + queueName +
|
||||||
", fullname=" + getQueuePath());
|
", fullname=" + getQueuePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void setupQueueConfigs(Resource clusterResource, float capacity,
|
synchronized void setupQueueConfigs(Resource clusterResource)
|
||||||
float absoluteCapacity, float maximumCapacity, float absoluteMaxCapacity,
|
throws IOException {
|
||||||
QueueState state, Map<AccessType, AccessControlList> acls,
|
super.setupQueueConfigs(clusterResource);
|
||||||
Set<String> accessibleLabels, String defaultLabelExpression,
|
StringBuilder aclsString = new StringBuilder();
|
||||||
Map<String, Float> nodeLabelCapacities,
|
|
||||||
Map<String, Float> maximumCapacitiesByLabel,
|
|
||||||
boolean reservationContinueLooking) throws IOException {
|
|
||||||
super.setupQueueConfigs(clusterResource, capacity, absoluteCapacity,
|
|
||||||
maximumCapacity, absoluteMaxCapacity, state, acls, accessibleLabels,
|
|
||||||
defaultLabelExpression, nodeLabelCapacities, maximumCapacitiesByLabel,
|
|
||||||
reservationContinueLooking, maximumAllocation);
|
|
||||||
StringBuilder aclsString = new StringBuilder();
|
|
||||||
for (Map.Entry<AccessType, AccessControlList> e : acls.entrySet()) {
|
for (Map.Entry<AccessType, AccessControlList> e : acls.entrySet()) {
|
||||||
aclsString.append(e.getKey() + ":" + e.getValue().getAclString());
|
aclsString.append(e.getKey() + ":" + e.getValue().getAclString());
|
||||||
}
|
}
|
||||||
|
@ -148,10 +122,10 @@ public class ParentQueue extends AbstractCSQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.info(queueName +
|
LOG.info(queueName +
|
||||||
", capacity=" + capacity +
|
", capacity=" + this.queueCapacities.getCapacity() +
|
||||||
", asboluteCapacity=" + absoluteCapacity +
|
", asboluteCapacity=" + this.queueCapacities.getAbsoluteCapacity() +
|
||||||
", maxCapacity=" + maximumCapacity +
|
", maxCapacity=" + this.queueCapacities.getMaximumCapacity() +
|
||||||
", asboluteMaxCapacity=" + absoluteMaxCapacity +
|
", asboluteMaxCapacity=" + this.queueCapacities.getAbsoluteMaximumCapacity() +
|
||||||
", state=" + state +
|
", state=" + state +
|
||||||
", acls=" + aclsString +
|
", acls=" + aclsString +
|
||||||
", labels=" + labelStrBuilder.toString() + "\n" +
|
", labels=" + labelStrBuilder.toString() + "\n" +
|
||||||
|
@ -167,19 +141,19 @@ public class ParentQueue extends AbstractCSQueue {
|
||||||
}
|
}
|
||||||
float delta = Math.abs(1.0f - childCapacities); // crude way to check
|
float delta = Math.abs(1.0f - childCapacities); // crude way to check
|
||||||
// allow capacities being set to 0, and enforce child 0 if parent is 0
|
// allow capacities being set to 0, and enforce child 0 if parent is 0
|
||||||
if (((capacity > 0) && (delta > PRECISION)) ||
|
if (((queueCapacities.getCapacity() > 0) && (delta > PRECISION)) ||
|
||||||
((capacity == 0) && (childCapacities > 0))) {
|
((queueCapacities.getCapacity() == 0) && (childCapacities > 0))) {
|
||||||
throw new IllegalArgumentException("Illegal" +
|
throw new IllegalArgumentException("Illegal" +
|
||||||
" capacity of " + childCapacities +
|
" capacity of " + childCapacities +
|
||||||
" for children of queue " + queueName);
|
" for children of queue " + queueName);
|
||||||
}
|
}
|
||||||
// check label capacities
|
// check label capacities
|
||||||
for (String nodeLabel : labelManager.getClusterNodeLabels()) {
|
for (String nodeLabel : labelManager.getClusterNodeLabels()) {
|
||||||
float capacityByLabel = getCapacityByNodeLabel(nodeLabel);
|
float capacityByLabel = queueCapacities.getCapacity(nodeLabel);
|
||||||
// check children's labels
|
// check children's labels
|
||||||
float sum = 0;
|
float sum = 0;
|
||||||
for (CSQueue queue : childQueues) {
|
for (CSQueue queue : childQueues) {
|
||||||
sum += queue.getCapacityByNodeLabel(nodeLabel);
|
sum += queue.getQueueCapacities().getCapacity(nodeLabel);
|
||||||
}
|
}
|
||||||
if ((capacityByLabel > 0 && Math.abs(1.0f - sum) > PRECISION)
|
if ((capacityByLabel > 0 && Math.abs(1.0f - sum) > PRECISION)
|
||||||
|| (capacityByLabel == 0) && (sum > 0)) {
|
|| (capacityByLabel == 0) && (sum > 0)) {
|
||||||
|
@ -255,8 +229,8 @@ public class ParentQueue extends AbstractCSQueue {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return queueName + ": " +
|
return queueName + ": " +
|
||||||
"numChildQueue= " + childQueues.size() + ", " +
|
"numChildQueue= " + childQueues.size() + ", " +
|
||||||
"capacity=" + capacity + ", " +
|
"capacity=" + queueCapacities.getCapacity() + ", " +
|
||||||
"absoluteCapacity=" + absoluteCapacity + ", " +
|
"absoluteCapacity=" + queueCapacities.getAbsoluteCapacity() + ", " +
|
||||||
"usedResources=" + queueUsage.getUsed() +
|
"usedResources=" + queueUsage.getUsed() +
|
||||||
"usedCapacity=" + getUsedCapacity() + ", " +
|
"usedCapacity=" + getUsedCapacity() + ", " +
|
||||||
"numApps=" + getNumApplications() + ", " +
|
"numApps=" + getNumApplications() + ", " +
|
||||||
|
@ -264,9 +238,8 @@ public class ParentQueue extends AbstractCSQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void reinitialize(
|
public synchronized void reinitialize(CSQueue newlyParsedQueue,
|
||||||
CSQueue newlyParsedQueue, Resource clusterResource)
|
Resource clusterResource) throws IOException {
|
||||||
throws IOException {
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if (!(newlyParsedQueue instanceof ParentQueue) ||
|
if (!(newlyParsedQueue instanceof ParentQueue) ||
|
||||||
!newlyParsedQueue.getQueuePath().equals(getQueuePath())) {
|
!newlyParsedQueue.getQueuePath().equals(getQueuePath())) {
|
||||||
|
@ -277,18 +250,7 @@ public class ParentQueue extends AbstractCSQueue {
|
||||||
ParentQueue newlyParsedParentQueue = (ParentQueue)newlyParsedQueue;
|
ParentQueue newlyParsedParentQueue = (ParentQueue)newlyParsedQueue;
|
||||||
|
|
||||||
// Set new configs
|
// Set new configs
|
||||||
setupQueueConfigs(clusterResource,
|
setupQueueConfigs(clusterResource);
|
||||||
newlyParsedParentQueue.capacity,
|
|
||||||
newlyParsedParentQueue.absoluteCapacity,
|
|
||||||
newlyParsedParentQueue.maximumCapacity,
|
|
||||||
newlyParsedParentQueue.absoluteMaxCapacity,
|
|
||||||
newlyParsedParentQueue.state,
|
|
||||||
newlyParsedParentQueue.acls,
|
|
||||||
newlyParsedParentQueue.accessibleLabels,
|
|
||||||
newlyParsedParentQueue.defaultLabelExpression,
|
|
||||||
newlyParsedParentQueue.capacitiyByNodeLabels,
|
|
||||||
newlyParsedParentQueue.maxCapacityByNodeLabels,
|
|
||||||
newlyParsedParentQueue.reservationsContinueLooking);
|
|
||||||
|
|
||||||
// Re-configure existing child queues and add new ones
|
// Re-configure existing child queues and add new ones
|
||||||
// The CS has already checked to ensure all existing child queues are present!
|
// The CS has already checked to ensure all existing child queues are present!
|
||||||
|
@ -513,7 +475,7 @@ public class ParentQueue extends AbstractCSQueue {
|
||||||
labelManager.getResourceByLabel(label, clusterResource));
|
labelManager.getResourceByLabel(label, clusterResource));
|
||||||
// if any of the label doesn't beyond limit, we can allocate on this node
|
// if any of the label doesn't beyond limit, we can allocate on this node
|
||||||
if (currentAbsoluteLabelUsedCapacity >=
|
if (currentAbsoluteLabelUsedCapacity >=
|
||||||
getAbsoluteMaximumCapacityByNodeLabel(label)) {
|
queueCapacities.getAbsoluteMaximumCapacity(label)) {
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug(getQueueName() + " used=" + queueUsage.getUsed()
|
LOG.debug(getQueueName() + " used=" + queueUsage.getUsed()
|
||||||
+ " current-capacity (" + queueUsage.getUsed(label) + ") "
|
+ " current-capacity (" + queueUsage.getUsed(label) + ") "
|
||||||
|
@ -541,7 +503,8 @@ public class ParentQueue extends AbstractCSQueue {
|
||||||
Resources.subtract(queueUsage.getUsed(), reservedResources),
|
Resources.subtract(queueUsage.getUsed(), reservedResources),
|
||||||
clusterResource);
|
clusterResource);
|
||||||
|
|
||||||
if (capacityWithoutReservedCapacity <= absoluteMaxCapacity) {
|
if (capacityWithoutReservedCapacity <= queueCapacities
|
||||||
|
.getAbsoluteMaximumCapacity()) {
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("parent: try to use reserved: " + getQueueName()
|
LOG.debug("parent: try to use reserved: " + getQueueName()
|
||||||
+ " usedResources: " + queueUsage.getUsed().getMemory()
|
+ " usedResources: " + queueUsage.getUsed().getMemory()
|
||||||
|
@ -551,7 +514,7 @@ public class ParentQueue extends AbstractCSQueue {
|
||||||
/ clusterResource.getMemory()
|
/ clusterResource.getMemory()
|
||||||
+ " potentialNewWithoutReservedCapacity: "
|
+ " potentialNewWithoutReservedCapacity: "
|
||||||
+ capacityWithoutReservedCapacity + " ( " + " max-capacity: "
|
+ capacityWithoutReservedCapacity + " ( " + " max-capacity: "
|
||||||
+ absoluteMaxCapacity + ")");
|
+ queueCapacities.getAbsoluteMaximumCapacity() + ")");
|
||||||
}
|
}
|
||||||
// we could potentially use this node instead of reserved node
|
// we could potentially use this node instead of reserved node
|
||||||
return true;
|
return true;
|
||||||
|
@ -761,13 +724,6 @@ public class ParentQueue extends AbstractCSQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getAbsActualCapacity() {
|
|
||||||
// for now, simply return actual capacity = guaranteed capacity for parent
|
|
||||||
// queue
|
|
||||||
return absoluteCapacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized int getNumApplications() {
|
public synchronized int getNumApplications() {
|
||||||
return numApplications;
|
return numApplications;
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
|
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.apache.hadoop.yarn.api.records.Resource;
|
import org.apache.hadoop.yarn.api.records.Resource;
|
||||||
|
@ -99,16 +97,7 @@ public class PlanQueue extends ParentQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set new configs
|
// Set new configs
|
||||||
setupQueueConfigs(clusterResource, newlyParsedParentQueue.getCapacity(),
|
setupQueueConfigs(clusterResource);
|
||||||
newlyParsedParentQueue.getAbsoluteCapacity(),
|
|
||||||
newlyParsedParentQueue.getMaximumCapacity(),
|
|
||||||
newlyParsedParentQueue.getAbsoluteMaximumCapacity(),
|
|
||||||
newlyParsedParentQueue.getState(), newlyParsedParentQueue.getACLs(),
|
|
||||||
newlyParsedParentQueue.accessibleLabels,
|
|
||||||
newlyParsedParentQueue.defaultLabelExpression,
|
|
||||||
newlyParsedParentQueue.capacitiyByNodeLabels,
|
|
||||||
newlyParsedParentQueue.maxCapacityByNodeLabels,
|
|
||||||
newlyParsedParentQueue.getReservationContinueLooking());
|
|
||||||
|
|
||||||
updateQuotas(newlyParsedParentQueue.userLimit,
|
updateQuotas(newlyParsedParentQueue.userLimit,
|
||||||
newlyParsedParentQueue.userLimitFactor,
|
newlyParsedParentQueue.userLimitFactor,
|
||||||
|
|
|
@ -19,12 +19,18 @@
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
|
package org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.hadoop.yarn.nodelabels.CommonNodeLabelsManager;
|
import org.apache.hadoop.yarn.nodelabels.CommonNodeLabelsManager;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
public class QueueCapacities {
|
public class QueueCapacities {
|
||||||
private static final String NL = CommonNodeLabelsManager.NO_LABEL;
|
private static final String NL = CommonNodeLabelsManager.NO_LABEL;
|
||||||
|
@ -32,13 +38,15 @@ public class QueueCapacities {
|
||||||
private Map<String, Capacities> capacitiesMap;
|
private Map<String, Capacities> capacitiesMap;
|
||||||
private ReadLock readLock;
|
private ReadLock readLock;
|
||||||
private WriteLock writeLock;
|
private WriteLock writeLock;
|
||||||
|
private final boolean isRoot;
|
||||||
|
|
||||||
public QueueCapacities() {
|
public QueueCapacities(boolean isRoot) {
|
||||||
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||||
readLock = lock.readLock();
|
readLock = lock.readLock();
|
||||||
writeLock = lock.writeLock();
|
writeLock = lock.writeLock();
|
||||||
|
|
||||||
capacitiesMap = new HashMap<String, Capacities>();
|
capacitiesMap = new HashMap<String, Capacities>();
|
||||||
|
this.isRoot = isRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Usage enum here to make implement cleaner
|
// Usage enum here to make implement cleaner
|
||||||
|
@ -58,6 +66,18 @@ public class QueueCapacities {
|
||||||
public Capacities() {
|
public Capacities() {
|
||||||
capacitiesArr = new float[CapacityType.values().length];
|
capacitiesArr = new float[CapacityType.values().length];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("{used=" + capacitiesArr[0] + "%, ");
|
||||||
|
sb.append("abs_used=" + capacitiesArr[1] + "%, ");
|
||||||
|
sb.append("max_cap=" + capacitiesArr[2] + "%, ");
|
||||||
|
sb.append("abs_max_cap=" + capacitiesArr[3] + "%, ");
|
||||||
|
sb.append("cap=" + capacitiesArr[4] + "%, ");
|
||||||
|
sb.append("abs_cap=" + capacitiesArr[5] + "%}");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float _get(String label, CapacityType type) {
|
private float _get(String label, CapacityType type) {
|
||||||
|
@ -127,6 +147,10 @@ public class QueueCapacities {
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getCapacity(String label) {
|
public float getCapacity(String label) {
|
||||||
|
if (StringUtils.equals(label, RMNodeLabelsManager.NO_LABEL) && isRoot) {
|
||||||
|
return 1f;
|
||||||
|
}
|
||||||
|
|
||||||
return _get(label, CapacityType.CAP);
|
return _get(label, CapacityType.CAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +168,9 @@ public class QueueCapacities {
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAbsoluteCapacity(String label) {
|
public float getAbsoluteCapacity(String label) {
|
||||||
|
if (StringUtils.equals(label, RMNodeLabelsManager.NO_LABEL) && isRoot) {
|
||||||
|
return 1f;
|
||||||
|
}
|
||||||
return _get(label, CapacityType.ABS_CAP);
|
return _get(label, CapacityType.ABS_CAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,4 +215,43 @@ public class QueueCapacities {
|
||||||
public void setAbsoluteMaximumCapacity(String label, float value) {
|
public void setAbsoluteMaximumCapacity(String label, float value) {
|
||||||
_set(label, CapacityType.ABS_MAX_CAP, value);
|
_set(label, CapacityType.ABS_MAX_CAP, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear configurable fields, like
|
||||||
|
* (absolute)capacity/(absolute)maximum-capacity, this will be used by queue
|
||||||
|
* reinitialize, when we reinitialize a queue, we will first clear all
|
||||||
|
* configurable fields, and load new values
|
||||||
|
*/
|
||||||
|
public void clearConfigurableFields() {
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
for (String label : capacitiesMap.keySet()) {
|
||||||
|
_set(label, CapacityType.CAP, 0);
|
||||||
|
_set(label, CapacityType.MAX_CAP, 0);
|
||||||
|
_set(label, CapacityType.ABS_CAP, 0);
|
||||||
|
_set(label, CapacityType.ABS_MAX_CAP, 0);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getExistingNodeLabels() {
|
||||||
|
try {
|
||||||
|
readLock.lock();
|
||||||
|
return new HashSet<String>(capacitiesMap.keySet());
|
||||||
|
} finally {
|
||||||
|
readLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
try {
|
||||||
|
readLock.lock();
|
||||||
|
return this.capacitiesMap.toString();
|
||||||
|
} finally {
|
||||||
|
readLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,11 +62,11 @@ public class ReservationQueue extends LeafQueue {
|
||||||
throw new IOException("Trying to reinitialize " + getQueuePath()
|
throw new IOException("Trying to reinitialize " + getQueuePath()
|
||||||
+ " from " + newlyParsedQueue.getQueuePath());
|
+ " from " + newlyParsedQueue.getQueuePath());
|
||||||
}
|
}
|
||||||
|
super.reinitialize(newlyParsedQueue, clusterResource);
|
||||||
CSQueueUtils.updateQueueStatistics(
|
CSQueueUtils.updateQueueStatistics(
|
||||||
parent.schedulerContext.getResourceCalculator(), newlyParsedQueue,
|
parent.schedulerContext.getResourceCalculator(), newlyParsedQueue,
|
||||||
parent, parent.schedulerContext.getClusterResource(),
|
parent, parent.schedulerContext.getClusterResource(),
|
||||||
parent.schedulerContext.getMinimumResourceCapability());
|
parent.schedulerContext.getMinimumResourceCapability());
|
||||||
super.reinitialize(newlyParsedQueue, clusterResource);
|
|
||||||
updateQuotas(parent.getUserLimitForReservation(),
|
updateQuotas(parent.getUserLimitForReservation(),
|
||||||
parent.getUserLimitFactor(),
|
parent.getUserLimitFactor(),
|
||||||
parent.getMaxApplicationsForReservations(),
|
parent.getMaxApplicationsForReservations(),
|
||||||
|
@ -108,9 +108,9 @@ public class ReservationQueue extends LeafQueue {
|
||||||
maxApplicationsPerUser = maxAppsPerUserForReservation;
|
maxApplicationsPerUser = maxAppsPerUserForReservation;
|
||||||
}
|
}
|
||||||
|
|
||||||
// used by the super constructor, we initialize to zero
|
@Override
|
||||||
protected float getCapacityFromConf() {
|
protected void setupConfigurableCapacities() {
|
||||||
return 0f;
|
CSQueueUtils.updateAndCheckCapacitiesByLabel(getQueuePath(),
|
||||||
|
queueCapacities, parent == null ? null : parent.getQueueCapacities());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,33 +202,33 @@ public class TestCSQueueUtils {
|
||||||
LOG.info("t2 l2q2 " + result);
|
LOG.info("t2 l2q2 " + result);
|
||||||
|
|
||||||
//some usage, but below the base capacity
|
//some usage, but below the base capacity
|
||||||
root.getResourceUsage().incUsed(Resources.multiply(clusterResource, 0.1f));
|
root.getQueueResourceUsage().incUsed(Resources.multiply(clusterResource, 0.1f));
|
||||||
l1q2.getResourceUsage().incUsed(Resources.multiply(clusterResource, 0.1f));
|
l1q2.getQueueResourceUsage().incUsed(Resources.multiply(clusterResource, 0.1f));
|
||||||
result = CSQueueUtils.getAbsoluteMaxAvailCapacity(
|
result = CSQueueUtils.getAbsoluteMaxAvailCapacity(
|
||||||
resourceCalculator, clusterResource, l2q2);
|
resourceCalculator, clusterResource, l2q2);
|
||||||
assertEquals( 0.4f, result, 0.000001f);
|
assertEquals( 0.4f, result, 0.000001f);
|
||||||
LOG.info("t2 l2q2 " + result);
|
LOG.info("t2 l2q2 " + result);
|
||||||
|
|
||||||
//usage gt base on parent sibling
|
//usage gt base on parent sibling
|
||||||
root.getResourceUsage().incUsed(Resources.multiply(clusterResource, 0.3f));
|
root.getQueueResourceUsage().incUsed(Resources.multiply(clusterResource, 0.3f));
|
||||||
l1q2.getResourceUsage().incUsed(Resources.multiply(clusterResource, 0.3f));
|
l1q2.getQueueResourceUsage().incUsed(Resources.multiply(clusterResource, 0.3f));
|
||||||
result = CSQueueUtils.getAbsoluteMaxAvailCapacity(
|
result = CSQueueUtils.getAbsoluteMaxAvailCapacity(
|
||||||
resourceCalculator, clusterResource, l2q2);
|
resourceCalculator, clusterResource, l2q2);
|
||||||
assertEquals( 0.3f, result, 0.000001f);
|
assertEquals( 0.3f, result, 0.000001f);
|
||||||
LOG.info("t2 l2q2 " + result);
|
LOG.info("t2 l2q2 " + result);
|
||||||
|
|
||||||
//same as last, but with usage also on direct parent
|
//same as last, but with usage also on direct parent
|
||||||
root.getResourceUsage().incUsed(Resources.multiply(clusterResource, 0.1f));
|
root.getQueueResourceUsage().incUsed(Resources.multiply(clusterResource, 0.1f));
|
||||||
l1q1.getResourceUsage().incUsed(Resources.multiply(clusterResource, 0.1f));
|
l1q1.getQueueResourceUsage().incUsed(Resources.multiply(clusterResource, 0.1f));
|
||||||
result = CSQueueUtils.getAbsoluteMaxAvailCapacity(
|
result = CSQueueUtils.getAbsoluteMaxAvailCapacity(
|
||||||
resourceCalculator, clusterResource, l2q2);
|
resourceCalculator, clusterResource, l2q2);
|
||||||
assertEquals( 0.3f, result, 0.000001f);
|
assertEquals( 0.3f, result, 0.000001f);
|
||||||
LOG.info("t2 l2q2 " + result);
|
LOG.info("t2 l2q2 " + result);
|
||||||
|
|
||||||
//add to direct sibling, below the threshold of effect at present
|
//add to direct sibling, below the threshold of effect at present
|
||||||
root.getResourceUsage().incUsed(Resources.multiply(clusterResource, 0.2f));
|
root.getQueueResourceUsage().incUsed(Resources.multiply(clusterResource, 0.2f));
|
||||||
l1q1.getResourceUsage().incUsed(Resources.multiply(clusterResource, 0.2f));
|
l1q1.getQueueResourceUsage().incUsed(Resources.multiply(clusterResource, 0.2f));
|
||||||
l2q1.getResourceUsage().incUsed(Resources.multiply(clusterResource, 0.2f));
|
l2q1.getQueueResourceUsage().incUsed(Resources.multiply(clusterResource, 0.2f));
|
||||||
result = CSQueueUtils.getAbsoluteMaxAvailCapacity(
|
result = CSQueueUtils.getAbsoluteMaxAvailCapacity(
|
||||||
resourceCalculator, clusterResource, l2q2);
|
resourceCalculator, clusterResource, l2q2);
|
||||||
assertEquals( 0.3f, result, 0.000001f);
|
assertEquals( 0.3f, result, 0.000001f);
|
||||||
|
@ -236,9 +236,9 @@ public class TestCSQueueUtils {
|
||||||
|
|
||||||
//add to direct sibling, now above the threshold of effect
|
//add to direct sibling, now above the threshold of effect
|
||||||
//(it's cumulative with prior tests)
|
//(it's cumulative with prior tests)
|
||||||
root.getResourceUsage().incUsed(Resources.multiply(clusterResource, 0.2f));
|
root.getQueueResourceUsage().incUsed(Resources.multiply(clusterResource, 0.2f));
|
||||||
l1q1.getResourceUsage().incUsed(Resources.multiply(clusterResource, 0.2f));
|
l1q1.getQueueResourceUsage().incUsed(Resources.multiply(clusterResource, 0.2f));
|
||||||
l2q1.getResourceUsage().incUsed(Resources.multiply(clusterResource, 0.2f));
|
l2q1.getQueueResourceUsage().incUsed(Resources.multiply(clusterResource, 0.2f));
|
||||||
result = CSQueueUtils.getAbsoluteMaxAvailCapacity(
|
result = CSQueueUtils.getAbsoluteMaxAvailCapacity(
|
||||||
resourceCalculator, clusterResource, l2q2);
|
resourceCalculator, clusterResource, l2q2);
|
||||||
assertEquals( 0.1f, result, 0.000001f);
|
assertEquals( 0.1f, result, 0.000001f);
|
||||||
|
|
|
@ -389,11 +389,11 @@ public class TestCapacityScheduler {
|
||||||
public void testMaximumCapacitySetup() {
|
public void testMaximumCapacitySetup() {
|
||||||
float delta = 0.0000001f;
|
float delta = 0.0000001f;
|
||||||
CapacitySchedulerConfiguration conf = new CapacitySchedulerConfiguration();
|
CapacitySchedulerConfiguration conf = new CapacitySchedulerConfiguration();
|
||||||
assertEquals(CapacitySchedulerConfiguration.MAXIMUM_CAPACITY_VALUE,conf.getMaximumCapacity(A),delta);
|
assertEquals(CapacitySchedulerConfiguration.MAXIMUM_CAPACITY_VALUE,conf.getNonLabeledQueueMaximumCapacity(A),delta);
|
||||||
conf.setMaximumCapacity(A, 50.0f);
|
conf.setMaximumCapacity(A, 50.0f);
|
||||||
assertEquals(50.0f, conf.getMaximumCapacity(A),delta);
|
assertEquals(50.0f, conf.getNonLabeledQueueMaximumCapacity(A),delta);
|
||||||
conf.setMaximumCapacity(A, -1);
|
conf.setMaximumCapacity(A, -1);
|
||||||
assertEquals(CapacitySchedulerConfiguration.MAXIMUM_CAPACITY_VALUE,conf.getMaximumCapacity(A),delta);
|
assertEquals(CapacitySchedulerConfiguration.MAXIMUM_CAPACITY_VALUE,conf.getNonLabeledQueueMaximumCapacity(A),delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,8 @@ public class TestCapacitySchedulerNodeLabelUpdate {
|
||||||
String label) {
|
String label) {
|
||||||
CapacityScheduler scheduler = (CapacityScheduler) rm.getResourceScheduler();
|
CapacityScheduler scheduler = (CapacityScheduler) rm.getResourceScheduler();
|
||||||
CSQueue queue = scheduler.getQueue(queueName);
|
CSQueue queue = scheduler.getQueue(queueName);
|
||||||
Assert.assertEquals(memory, queue.getUsedResourceByLabel(label).getMemory());
|
Assert.assertEquals(memory, queue.getQueueResourceUsage().getUsed(label)
|
||||||
|
.getMemory());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test (timeout = 30000)
|
@Test (timeout = 30000)
|
||||||
|
|
|
@ -99,7 +99,7 @@ public class TestQueueCapacities {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void internalTestModifyAndRead(String label) throws Exception {
|
private void internalTestModifyAndRead(String label) throws Exception {
|
||||||
QueueCapacities qc = new QueueCapacities();
|
QueueCapacities qc = new QueueCapacities(false);
|
||||||
|
|
||||||
// First get returns 0 always
|
// First get returns 0 always
|
||||||
Assert.assertEquals(0f, get(qc, suffix, label), 1e-8);
|
Assert.assertEquals(0f, get(qc, suffix, label), 1e-8);
|
||||||
|
|
|
@ -468,18 +468,18 @@ public class TestQueueParsing {
|
||||||
// check capacity of A2
|
// check capacity of A2
|
||||||
CSQueue qA2 = capacityScheduler.getQueue("a2");
|
CSQueue qA2 = capacityScheduler.getQueue("a2");
|
||||||
Assert.assertEquals(0.7, qA2.getCapacity(), DELTA);
|
Assert.assertEquals(0.7, qA2.getCapacity(), DELTA);
|
||||||
Assert.assertEquals(0.5, qA2.getCapacityByNodeLabel("red"), DELTA);
|
Assert.assertEquals(0.5, qA2.getQueueCapacities().getCapacity("red"), DELTA);
|
||||||
Assert.assertEquals(0.07, qA2.getAbsoluteCapacity(), DELTA);
|
Assert.assertEquals(0.07, qA2.getAbsoluteCapacity(), DELTA);
|
||||||
Assert.assertEquals(0.25, qA2.getAbsoluteCapacityByNodeLabel("red"), DELTA);
|
Assert.assertEquals(0.25, qA2.getQueueCapacities().getAbsoluteCapacity("red"), DELTA);
|
||||||
Assert.assertEquals(0.1275, qA2.getAbsoluteMaximumCapacity(), DELTA);
|
Assert.assertEquals(0.1275, qA2.getAbsoluteMaximumCapacity(), DELTA);
|
||||||
Assert.assertEquals(0.3, qA2.getAbsoluteMaximumCapacityByNodeLabel("red"), DELTA);
|
Assert.assertEquals(0.3, qA2.getQueueCapacities().getAbsoluteMaximumCapacity("red"), DELTA);
|
||||||
|
|
||||||
// check capacity of B3
|
// check capacity of B3
|
||||||
CSQueue qB3 = capacityScheduler.getQueue("b3");
|
CSQueue qB3 = capacityScheduler.getQueue("b3");
|
||||||
Assert.assertEquals(0.18, qB3.getAbsoluteCapacity(), DELTA);
|
Assert.assertEquals(0.18, qB3.getAbsoluteCapacity(), DELTA);
|
||||||
Assert.assertEquals(0.125, qB3.getAbsoluteCapacityByNodeLabel("red"), DELTA);
|
Assert.assertEquals(0.125, qB3.getQueueCapacities().getAbsoluteCapacity("red"), DELTA);
|
||||||
Assert.assertEquals(0.35, qB3.getAbsoluteMaximumCapacity(), DELTA);
|
Assert.assertEquals(0.35, qB3.getAbsoluteMaximumCapacity(), DELTA);
|
||||||
Assert.assertEquals(1, qB3.getAbsoluteMaximumCapacityByNodeLabel("red"), DELTA);
|
Assert.assertEquals(1, qB3.getQueueCapacities().getAbsoluteMaximumCapacity("red"), DELTA);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void
|
private void
|
||||||
|
@ -691,8 +691,8 @@ public class TestQueueParsing {
|
||||||
|
|
||||||
// check root queue's capacity by label -- they should be all zero
|
// check root queue's capacity by label -- they should be all zero
|
||||||
CSQueue root = capacityScheduler.getQueue(CapacitySchedulerConfiguration.ROOT);
|
CSQueue root = capacityScheduler.getQueue(CapacitySchedulerConfiguration.ROOT);
|
||||||
Assert.assertEquals(0, root.getCapacityByNodeLabel("red"), DELTA);
|
Assert.assertEquals(0, root.getQueueCapacities().getCapacity("red"), DELTA);
|
||||||
Assert.assertEquals(0, root.getCapacityByNodeLabel("blue"), DELTA);
|
Assert.assertEquals(0, root.getQueueCapacities().getCapacity("blue"), DELTA);
|
||||||
|
|
||||||
CSQueue a = capacityScheduler.getQueue("a");
|
CSQueue a = capacityScheduler.getQueue("a");
|
||||||
Assert.assertEquals(0.10, a.getAbsoluteCapacity(), DELTA);
|
Assert.assertEquals(0.10, a.getAbsoluteCapacity(), DELTA);
|
||||||
|
|
|
@ -395,9 +395,9 @@ public class TestRMWebServicesCapacitySched extends JerseyTestBase {
|
||||||
String qshortName = qArr[qArr.length - 1];
|
String qshortName = qArr[qArr.length - 1];
|
||||||
|
|
||||||
assertEquals("usedCapacity doesn't match", 0, info.usedCapacity, 1e-3f);
|
assertEquals("usedCapacity doesn't match", 0, info.usedCapacity, 1e-3f);
|
||||||
assertEquals("capacity doesn't match", csConf.getCapacity(q),
|
assertEquals("capacity doesn't match", csConf.getNonLabeledQueueCapacity(q),
|
||||||
info.capacity, 1e-3f);
|
info.capacity, 1e-3f);
|
||||||
float expectCapacity = csConf.getMaximumCapacity(q);
|
float expectCapacity = csConf.getNonLabeledQueueMaximumCapacity(q);
|
||||||
float expectAbsMaxCapacity = parentAbsMaxCapacity * (info.maxCapacity/100);
|
float expectAbsMaxCapacity = parentAbsMaxCapacity * (info.maxCapacity/100);
|
||||||
if (CapacitySchedulerConfiguration.UNDEFINED == expectCapacity) {
|
if (CapacitySchedulerConfiguration.UNDEFINED == expectCapacity) {
|
||||||
expectCapacity = 100;
|
expectCapacity = 100;
|
||||||
|
|
Loading…
Reference in New Issue