YARN-7469. Capacity Scheduler Intra-queue preemption: User can starve if newest app is exactly at user limit. Contributed by Eric Payne.
(cherry picked from commit61ace174cd
) (cherry picked from commitc3fb49667a
)
This commit is contained in:
parent
b1712f9c1f
commit
0510ceede6
|
@ -203,6 +203,12 @@ public class FifoIntraQueuePreemptionPlugin
|
||||||
Resources.subtractFromNonNegative(preemtableFromApp, tmpApp.selected);
|
Resources.subtractFromNonNegative(preemtableFromApp, tmpApp.selected);
|
||||||
Resources.subtractFromNonNegative(preemtableFromApp, tmpApp.getAMUsed());
|
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:
|
// Calculate toBePreempted from apps as follows:
|
||||||
// app.preemptable = min(max(app.used - app.selected - app.ideal, 0),
|
// app.preemptable = min(max(app.used - app.selected - app.ideal, 0),
|
||||||
// intra_q_preemptable)
|
// intra_q_preemptable)
|
||||||
|
|
|
@ -358,6 +358,9 @@ public class ProportionalCapacityPreemptionPolicyMockFramework {
|
||||||
queue = (LeafQueue) nameToCSQueues.get(queueName);
|
queue = (LeafQueue) nameToCSQueues.get(queueName);
|
||||||
queue.getApplications().add(app);
|
queue.getApplications().add(app);
|
||||||
queue.getAllApplications().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);
|
HashSet<String> users = userMap.get(queueName);
|
||||||
if (null == users) {
|
if (null == users) {
|
||||||
|
|
|
@ -896,4 +896,39 @@ public class TestProportionalCapacityPreemptionPolicyIntraQueueUserLimit
|
||||||
new TestProportionalCapacityPreemptionPolicy.IsPreemptionRequestFor(
|
new TestProportionalCapacityPreemptionPolicy.IsPreemptionRequestFor(
|
||||||
getAppAttemptId(1))));
|
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