YARN-7469. Capacity Scheduler Intra-queue preemption: User can starve if newest app is exactly at user limit. Contributed by Eric Payne.
This commit is contained in:
parent
f4d5d20286
commit
61ace174cd
|
@ -203,6 +203,12 @@ public class FifoIntraQueuePreemptionPlugin
|
|||
Resources.subtractFromNonNegative(preemtableFromApp, tmpApp.selected);
|
||||
Resources.subtractFromNonNegative(preemtableFromApp, tmpApp.getAMUsed());
|
||||
|
||||
if (context.getIntraQueuePreemptionOrderPolicy()
|
||||
.equals(IntraQueuePreemptionOrderPolicy.USERLIMIT_FIRST)) {
|
||||
Resources.subtractFromNonNegative(preemtableFromApp,
|
||||
tmpApp.getFiCaSchedulerApp().getCSLeafQueue().getMinimumAllocation());
|
||||
}
|
||||
|
||||
// Calculate toBePreempted from apps as follows:
|
||||
// app.preemptable = min(max(app.used - app.selected - app.ideal, 0),
|
||||
// intra_q_preemptable)
|
||||
|
|
|
@ -358,6 +358,9 @@ public class ProportionalCapacityPreemptionPolicyMockFramework {
|
|||
queue = (LeafQueue) nameToCSQueues.get(queueName);
|
||||
queue.getApplications().add(app);
|
||||
queue.getAllApplications().add(app);
|
||||
when(queue.getMinimumAllocation())
|
||||
.thenReturn(Resource.newInstance(1,1));
|
||||
when(app.getCSLeafQueue()).thenReturn(queue);
|
||||
|
||||
HashSet<String> users = userMap.get(queueName);
|
||||
if (null == users) {
|
||||
|
|
|
@ -896,4 +896,39 @@ public class TestProportionalCapacityPreemptionPolicyIntraQueueUserLimit
|
|||
new TestProportionalCapacityPreemptionPolicy.IsPreemptionRequestFor(
|
||||
getAppAttemptId(1))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleIntraQueuePreemptionOneUserUnderOneUserAtOneUserAbove()
|
||||
throws IOException {
|
||||
conf.setFloat(CapacitySchedulerConfiguration.
|
||||
INTRAQUEUE_PREEMPTION_MAX_ALLOWABLE_LIMIT,
|
||||
(float) 0.5);
|
||||
|
||||
String labelsConfig = "=100,true;";
|
||||
String nodesConfig = // n1 has no label
|
||||
"n1= res=100";
|
||||
String queuesConfig =
|
||||
// guaranteed,max,used,pending,reserved
|
||||
"root(=[100 100 100 1 0]);" + // root
|
||||
"-a(=[100 100 100 1 0])"; // a
|
||||
|
||||
String appsConfig =
|
||||
// queueName\t(priority,resource,host,expression,#repeat,reserved,pending)
|
||||
"a\t" // app1 in a
|
||||
+ "(1,1,n1,,65,false,0,user1);" +
|
||||
"a\t" // app2 in a
|
||||
+ "(1,1,n1,,35,false,0,user2);" +
|
||||
"a\t" // app3 in a
|
||||
+ "(1,1,n1,,0,false,1,user3)"
|
||||
;
|
||||
|
||||
buildEnv(labelsConfig, nodesConfig, queuesConfig, appsConfig);
|
||||
policy.editSchedule();
|
||||
|
||||
// app2 is right at its user limit and app1 needs one resource. Should
|
||||
// preempt 1 container.
|
||||
verify(mDisp, times(1)).handle(argThat(
|
||||
new TestProportionalCapacityPreemptionPolicy.IsPreemptionRequestFor(
|
||||
getAppAttemptId(1))));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue