Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -408,9 +408,8 @@ public void setAverageCapacity(int avgCapacity) {
* Initialize a {@link FSQueue} with queue-specific properties and its
* metrics.
* @param queue the FSQueue needed to be initialized
* @param scheduler the scheduler which the queue belonged to
*/
public void initFSQueue(FSQueue queue, FairScheduler scheduler){
public void initFSQueue(FSQueue queue){
// Set queue-specific properties.
String name = queue.getName();
queue.setWeights(getQueueWeight(name));
Expand All @@ -419,14 +418,6 @@ public void initFSQueue(FSQueue queue, FairScheduler scheduler){
queue.setMaxRunningApps(getQueueMaxApps(name));
queue.setMaxAMShare(getQueueMaxAMShare(name));
queue.setMaxChildQueueResource(getMaxChildResources(name));
try {
SchedulingPolicy policy = getSchedulingPolicy(name);
policy.initialize(scheduler.getClusterResource());
queue.setPolicy(policy);
} catch (AllocationConfigurationException ex) {
LOG.warn("Failed to set the scheduling policy "
+ getDefaultSchedulingPolicy(), ex);
}

// Set queue metrics.
queue.getMetrics().setMinShare(getMinResources(name));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,15 +197,6 @@ public void collectSchedulerApplications(
}
}

@Override
public void setPolicy(SchedulingPolicy policy)
throws AllocationConfigurationException {
if (!SchedulingPolicy.isApplicableTo(policy, SchedulingPolicy.DEPTH_LEAF)) {
throwPolicyDoesnotApplyException(policy);
}
super.policy = policy;
}

@Override
public void updateInternal(boolean checkStarvation) {
readLock.lock();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,19 +239,6 @@ public List<FSQueue> getChildQueues() {
}
}

@Override
public void setPolicy(SchedulingPolicy policy)
throws AllocationConfigurationException {
boolean allowed =
SchedulingPolicy.isApplicableTo(policy, (parent == null)
? SchedulingPolicy.DEPTH_ROOT
: SchedulingPolicy.DEPTH_INTERMEDIATE);
if (!allowed) {
throwPolicyDoesnotApplyException(policy);
}
super.policy = policy;
}

void incrementRunnableApps() {
writeLock.lock();
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,23 @@ public FSQueue(String name, FairScheduler scheduler, FSParentQueue parent) {
this.queueEntity = new PrivilegedEntity(EntityType.QUEUE, name);
this.metrics = FSQueueMetrics.forQueue(getName(), parent, true, scheduler.getConf());
this.parent = parent;
setPolicy(scheduler.getAllocationConfiguration().getSchedulingPolicy(name));
reinit(false);
}

/**
* Initialize a queue by setting its queue-specific properties and its
* metrics.
* This function is invoked when a new queue is created or reloading the
* allocation configuration.
* metrics. This method is invoked when creating a new queue or reloading
* the allocation file.
* This method does not set policies for queues when reloading the allocation
* file since we need to either set all new policies or nothing, which is
* handled by method {@link #verifyAndSetPolicyFromConf}.
*
* @param recursive whether child queues should be reinitialized recursively
*/
public void reinit(boolean recursive) {
AllocationConfiguration allocConf = scheduler.getAllocationConfiguration();
allocConf.initFSQueue(this, scheduler);
allocConf.initFSQueue(this);
updatePreemptionVariables();

if (recursive) {
Expand All @@ -131,15 +134,11 @@ public FSParentQueue getParent() {
return parent;
}

protected void throwPolicyDoesnotApplyException(SchedulingPolicy policy)
throws AllocationConfigurationException {
throw new AllocationConfigurationException("SchedulingPolicy " + policy
+ " does not apply to queue " + getName());
public void setPolicy(SchedulingPolicy policy) {
policy.initialize(scheduler.getClusterResource());
this.policy = policy;
}

public abstract void setPolicy(SchedulingPolicy policy)
throws AllocationConfigurationException;

public void setWeights(ResourceWeights weights){
this.weights = weights;
}
Expand Down Expand Up @@ -463,4 +462,33 @@ boolean fitsInMaxShare(Resource additionalResource) {
}
return true;
}

/**
* Recursively check policies for queues in pre-order. Get queue policies
* from the allocation file instead of properties of {@link FSQueue} objects.
* Set the policy for current queue if there is no policy violation for its
* children. This method is invoked while reloading the allocation file.
*
* @param queueConf allocation configuration
* @return true if no policy violation and successfully set polices
* for queues; false otherwise
*/
public boolean verifyAndSetPolicyFromConf(AllocationConfiguration queueConf) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worthwhile to point out the intended caller for this method.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

SchedulingPolicy queuePolicy = queueConf.getSchedulingPolicy(getName());

for (FSQueue child : getChildQueues()) {
if (!queuePolicy.isChildPolicyAllowed(
queueConf.getSchedulingPolicy(child.getName()))) {
return false;
}
boolean success = child.verifyAndSetPolicyFromConf(queueConf);
if (!success) {
return false;
}
}

// Set the policy if no policy violation for all children
setPolicy(queuePolicy);
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,18 @@
import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.policies.FifoPolicy;
import org.xml.sax.SAXException;

import com.google.common.base.CharMatcher;
import com.google.common.annotations.VisibleForTesting;
import java.util.Iterator;
import java.util.Set;
import org.apache.hadoop.yarn.api.records.Resource;

/**
* Maintains a list of queues as well as scheduling parameters for each queue,
* such as guaranteed share allocations, from the fair scheduler config file.
*
*/
@Private
@Unstable
Expand All @@ -72,6 +73,9 @@ public FSParentQueue getRootQueue() {

public void initialize(Configuration conf) throws IOException,
SAXException, AllocationConfigurationException, ParserConfigurationException {
// Policies of root and default queue are set to
// SchedulingPolicy.DEFAULT_POLICY since the allocation file hasn't been
// loaded yet.
rootQueue = new FSParentQueue("root", scheduler, null);
queues.put(rootQueue.getName(), rootQueue);

Expand All @@ -80,7 +84,7 @@ public void initialize(Configuration conf) throws IOException,
// Recursively reinitialize to propagate queue properties
rootQueue.reinit(true);
}

/**
* Get a leaf queue by name, creating it if the create param is true and is necessary.
* If the queue is not or can not be a leaf queue, i.e. it already exists as a
Expand Down Expand Up @@ -272,12 +276,25 @@ private FSQueue createNewQueues(FSQueueType queueType,
FSParentQueue newParent = null;
String queueName = i.next();

// Check if child policy is allowed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this check be in setPolicy or the FSQueue constructor instead?

For instance, FSLeafQueue#setPolicy already checks if the level is appropriate. This brings up another point - do we need this check of parent-child policies AND the depth? Should we get rid of depth either in this JIRA or a follow-up?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, my original thought is to do that in another JIRA. The depth and parent-child policy are not the same. It mighty a good idea to combine them since the logic of depth checking only prevent fifo policy to be non-leaf queue. The current implementation seems a bit heavy. I can do it in this JIRA.

SchedulingPolicy childPolicy = scheduler.getAllocationConfiguration().
getSchedulingPolicy(queueName);
if (!parent.getPolicy().isChildPolicyAllowed(childPolicy)) {
LOG.error("Can't create queue '" + queueName + "'.");
return null;
}

// Only create a leaf queue at the very end
if (!i.hasNext() && (queueType != FSQueueType.PARENT)) {
FSLeafQueue leafQueue = new FSLeafQueue(queueName, scheduler, parent);
leafQueues.add(leafQueue);
queue = leafQueue;
} else {
if (childPolicy instanceof FifoPolicy) {
LOG.error("Can't create queue '" + queueName + "', since "
+ FifoPolicy.NAME + " is only for leaf queues.");
return null;
}
newParent = new FSParentQueue(queueName, scheduler, parent);
queue = newParent;
}
Expand Down Expand Up @@ -479,6 +496,13 @@ private String ensureRootPrefix(String name) {
public void updateAllocationConfiguration(AllocationConfiguration queueConf) {
// Create leaf queues and the parent queues in a leaf's ancestry if they do not exist
synchronized (queues) {
// Verify and set scheduling policies for existing queues before creating
// any queue, since we need parent policies to determine if we can create
// its children.
if (!rootQueue.verifyAndSetPolicyFromConf(queueConf)) {
LOG.error("Setting scheduling policies for existing queues failed!");
}

for (String name : queueConf.getConfiguredQueues().get(
FSQueueType.LEAF)) {
if (removeEmptyIncompatibleQueues(name, FSQueueType.LEAF)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ public abstract class SchedulingPolicy {
public static final SchedulingPolicy DEFAULT_POLICY =
getInstance(FairSharePolicy.class);

public static final byte DEPTH_LEAF = (byte) 1;
public static final byte DEPTH_INTERMEDIATE = (byte) 2;
public static final byte DEPTH_ROOT = (byte) 4;
public static final byte DEPTH_PARENT = (byte) 6; // Root and Intermediate
public static final byte DEPTH_ANY = (byte) 7;

/**
* Returns a {@link SchedulingPolicy} instance corresponding to the passed clazz
*/
Expand Down Expand Up @@ -113,27 +107,6 @@ public void initialize(Resource clusterCapacity) {}
*/
public abstract String getName();

/**
* Specifies the depths in the hierarchy, this {@link SchedulingPolicy}
* applies to
*
* @return depth equal to one of fields {@link SchedulingPolicy}#DEPTH_*
*/
public abstract byte getApplicableDepth();

/**
* Checks if the specified {@link SchedulingPolicy} can be used for a queue at
* the specified depth in the hierarchy
*
* @param policy {@link SchedulingPolicy} we are checking the
* depth-applicability for
* @param depth queue's depth in the hierarchy
* @return true if policy is applicable to passed depth, false otherwise
*/
public static boolean isApplicableTo(SchedulingPolicy policy, byte depth) {
return ((policy.getApplicableDepth() & depth) == depth) ? true : false;
}

/**
* The comparator returned by this method is to be used for sorting the
* {@link Schedulable}s in that queue.
Expand Down Expand Up @@ -191,4 +164,13 @@ public abstract boolean checkIfUsageOverFairShare(
public abstract Resource getHeadroom(Resource queueFairShare,
Resource queueUsage, Resource maxAvailable);

/**
* Check whether the policy of a child queue is allowed.
*
* @param childPolicy the policy of child queue
* @return true if the child policy is allowed; false otherwise
*/
public boolean isChildPolicyAllowed(SchedulingPolicy childPolicy) {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@ public String getName() {
return NAME;
}

@Override
public byte getApplicableDepth() {
return SchedulingPolicy.DEPTH_ANY;
}

@Override
public Comparator<Schedulable> getComparator() {
return COMPARATOR;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.util.Collection;
import java.util.Comparator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience.Private;
import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.yarn.api.records.Resource;
Expand All @@ -40,6 +42,7 @@
@Private
@Unstable
public class FairSharePolicy extends SchedulingPolicy {
private static final Log LOG = LogFactory.getLog(FifoPolicy.class);
@VisibleForTesting
public static final String NAME = "fair";
private static final DefaultResourceCalculator RESOURCE_CALCULATOR =
Expand Down Expand Up @@ -175,7 +178,15 @@ public boolean checkIfUsageOverFairShare(Resource usage, Resource fairShare) {
}

@Override
public byte getApplicableDepth() {
return SchedulingPolicy.DEPTH_ANY;
public boolean isChildPolicyAllowed(SchedulingPolicy childPolicy) {
if (childPolicy instanceof DominantResourceFairnessPolicy) {
LOG.error("Queue policy can't be " + DominantResourceFairnessPolicy.NAME
+ " if the parent policy is " + getName() + ". Choose " +
getName() + " or " + FifoPolicy.NAME + " for child queues instead."
+ " Please note that " + FifoPolicy.NAME
+ " is only for leaf queues.");
return false;
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
import java.util.Collection;
import java.util.Comparator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience.Private;
import org.apache.hadoop.classification.InterfaceStability.Unstable;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FSQueue;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.Schedulable;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.SchedulingPolicy;


import org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator;
import org.apache.hadoop.yarn.util.resource.ResourceCalculator;
import org.apache.hadoop.yarn.util.resource.Resources;
Expand All @@ -38,6 +38,8 @@
@Private
@Unstable
public class FifoPolicy extends SchedulingPolicy {
private static final Log LOG = LogFactory.getLog(FifoPolicy.class);

@VisibleForTesting
public static final String NAME = "FIFO";
private static final FifoComparator COMPARATOR = new FifoComparator();
Expand Down Expand Up @@ -127,9 +129,11 @@ public Resource getHeadroom(Resource queueFairShare,
return headroom;
}


@Override
public byte getApplicableDepth() {
return SchedulingPolicy.DEPTH_LEAF;
public boolean isChildPolicyAllowed(SchedulingPolicy childPolicy) {
LOG.error(getName() + " policy is only for leaf queues. Please choose "
+ DominantResourceFairnessPolicy.NAME + " or " + FairSharePolicy.NAME
+ " for parent queues.");
return false;
}
}
Loading