YARN-10632. Make auto queue creation maximum allowed depth configurable (#3859)
This commit is contained in:
parent
b88d5ae1c6
commit
21fe0e63fd
@ -426,6 +426,19 @@ public class CapacitySchedulerConfiguration extends ReservationSchedulerConfigur
|
|||||||
|
|
||||||
private ConfigurationProperties configurationProperties;
|
private ConfigurationProperties configurationProperties;
|
||||||
|
|
||||||
|
public int getMaximumAutoCreatedQueueDepth(String queuePath) {
|
||||||
|
return getInt(getQueuePrefix(queuePath) + MAXIMUM_QUEUE_DEPTH,
|
||||||
|
getInt(PREFIX + MAXIMUM_QUEUE_DEPTH, DEFAULT_MAXIMUM_QUEUE_DEPTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaximumAutoCreatedQueueDepth(String queuePath, int value) {
|
||||||
|
setInt(getQueuePrefix(queuePath) + MAXIMUM_QUEUE_DEPTH, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaximumAutoCreatedQueueDepth(int value) {
|
||||||
|
setInt(PREFIX + MAXIMUM_QUEUE_DEPTH, value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Different resource types supported.
|
* Different resource types supported.
|
||||||
*/
|
*/
|
||||||
@ -2136,6 +2149,13 @@ public void setDefaultLifetimePerQueue(String queue, long defaultLifetime) {
|
|||||||
public static final int
|
public static final int
|
||||||
DEFAULT_AUTO_QUEUE_CREATION_V2_MAX_QUEUES = 1000;
|
DEFAULT_AUTO_QUEUE_CREATION_V2_MAX_QUEUES = 1000;
|
||||||
|
|
||||||
|
@Private
|
||||||
|
public static final String MAXIMUM_QUEUE_DEPTH =
|
||||||
|
AUTO_QUEUE_CREATION_V2_PREFIX + "maximum-queue-depth";
|
||||||
|
|
||||||
|
@Private
|
||||||
|
public static final int DEFAULT_MAXIMUM_QUEUE_DEPTH = 2;
|
||||||
|
|
||||||
@Private
|
@Private
|
||||||
public static final boolean DEFAULT_AUTO_QUEUE_CREATION_ENABLED = false;
|
public static final boolean DEFAULT_AUTO_QUEUE_CREATION_ENABLED = false;
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -72,7 +73,6 @@ public CSQueue hook(CSQueue queue) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int MAXIMUM_DYNAMIC_QUEUE_DEPTH = 2;
|
|
||||||
private static final QueueHook NOOP = new QueueHook();
|
private static final QueueHook NOOP = new QueueHook();
|
||||||
private CapacitySchedulerContext csContext;
|
private CapacitySchedulerContext csContext;
|
||||||
private final YarnAuthorizationProvider authorizer;
|
private final YarnAuthorizationProvider authorizer;
|
||||||
@ -592,14 +592,6 @@ public List<String> determineMissingParents(
|
|||||||
&& parentCandidate.length() != 0) {
|
&& parentCandidate.length() != 0) {
|
||||||
++firstStaticParentDistance;
|
++firstStaticParentDistance;
|
||||||
|
|
||||||
if (firstStaticParentDistance > MAXIMUM_DYNAMIC_QUEUE_DEPTH) {
|
|
||||||
throw new SchedulerDynamicEditException(
|
|
||||||
"Could not auto create queue " + queue.getFullPath()
|
|
||||||
+ ". The distance of the LeafQueue from the first static " +
|
|
||||||
"ParentQueue is " + firstStaticParentDistance + ", which is " +
|
|
||||||
"above the limit.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstExistingParent == null) {
|
if (firstExistingParent == null) {
|
||||||
parentsToCreate.addFirst(parentCandidate.toString());
|
parentsToCreate.addFirst(parentCandidate.toString());
|
||||||
}
|
}
|
||||||
@ -614,6 +606,16 @@ public List<String> determineMissingParents(
|
|||||||
firstExistingStaticParent = getQueue(parentCandidate.toString());
|
firstExistingStaticParent = getQueue(parentCandidate.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int maximumDepthOfStaticParent = csContext.getConfiguration().getMaximumAutoCreatedQueueDepth(
|
||||||
|
firstExistingStaticParent.getQueuePath());
|
||||||
|
if (firstStaticParentDistance > maximumDepthOfStaticParent) {
|
||||||
|
throw new SchedulerDynamicEditException(
|
||||||
|
"Could not auto create queue " + queue.getFullPath()
|
||||||
|
+ ". The distance of the LeafQueue from the first static " +
|
||||||
|
"ParentQueue is " + firstStaticParentDistance + ", which is " +
|
||||||
|
"above the limit.");
|
||||||
|
}
|
||||||
|
|
||||||
if (!(firstExistingParent instanceof ParentQueue)) {
|
if (!(firstExistingParent instanceof ParentQueue)) {
|
||||||
throw new SchedulerDynamicEditException(
|
throw new SchedulerDynamicEditException(
|
||||||
"Could not auto create hierarchy of "
|
"Could not auto create hierarchy of "
|
||||||
|
@ -318,11 +318,40 @@ public void testAutoCreateQueueWhenSiblingsNotInWeightMode()
|
|||||||
createQueue("root.a.a2-auto");
|
createQueue("root.a.a2-auto");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SchedulerDynamicEditException.class)
|
@Test()
|
||||||
public void testAutoCreateQueueShouldFailIfDepthIsAboveLimit()
|
public void testAutoCreateMaximumQueueDepth()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
startScheduler();
|
startScheduler();
|
||||||
|
// By default, max depth is 2, therefore this is an invalid scenario
|
||||||
|
Assert.assertThrows(SchedulerDynamicEditException.class,
|
||||||
|
() -> createQueue("root.a.a3-auto.a4-auto.a5-auto"));
|
||||||
|
|
||||||
|
// Set depth 3 for root.a, making it a valid scenario
|
||||||
|
csConf.setMaximumAutoCreatedQueueDepth("root.a", 3);
|
||||||
|
cs.reinitialize(csConf, mockRM.getRMContext());
|
||||||
|
try {
|
||||||
createQueue("root.a.a3-auto.a4-auto.a5-auto");
|
createQueue("root.a.a3-auto.a4-auto.a5-auto");
|
||||||
|
} catch (SchedulerDynamicEditException sde) {
|
||||||
|
LOG.error("%s", sde);
|
||||||
|
Assert.fail("Depth is set for root.a, exception should not be thrown");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set global depth to 3
|
||||||
|
csConf.setMaximumAutoCreatedQueueDepth(3);
|
||||||
|
csConf.unset(CapacitySchedulerConfiguration.getQueuePrefix("root.a")
|
||||||
|
+ CapacitySchedulerConfiguration.MAXIMUM_QUEUE_DEPTH);
|
||||||
|
cs.reinitialize(csConf, mockRM.getRMContext());
|
||||||
|
try {
|
||||||
|
createQueue("root.a.a6-auto.a7-auto.a8-auto");
|
||||||
|
} catch (SchedulerDynamicEditException sde) {
|
||||||
|
LOG.error("%s", sde);
|
||||||
|
Assert.fail("Depth is set globally, exception should not be thrown");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set depth on a dynamic queue, which has no effect on auto queue creation validation
|
||||||
|
csConf.setMaximumAutoCreatedQueueDepth("root.a.a6-auto.a7-auto.a8-auto", 10);
|
||||||
|
Assert.assertThrows(SchedulerDynamicEditException.class,
|
||||||
|
() -> createQueue("root.a.a6-auto.a7-auto.a8-auto.a9-auto.a10-auto.a11-auto"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = SchedulerDynamicEditException.class)
|
@Test(expected = SchedulerDynamicEditException.class)
|
||||||
|
Loading…
Reference in New Issue
Block a user