FairScheduler类
private class UpdateThread extends Thread {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(updateInterval); //默认500ms
long start = getClock().getTime();
update();
preemptTasksIfNecessary(); /抢占
long duration = getClock().getTime() - start;
fsOpDurations.addUpdateThreadRunDuration(duration);
} catch (InterruptedException ie) {
LOG.warn("Update thread interrupted. Exiting.");
return;
} catch (Exception e) {
LOG.error("Exception in fair scheduler UpdateThread", e);
}
}
}
}
protected synchronized void preemptTasksIfNecessary() {
if (!shouldAttemptPreemption()) { 判断是否应该尝试抢占
return;
}
long curTime = getClock().getTime();
if (curTime - lastPreemptCheckTime < preemptionInterval) { ///抢占间隔 ,默认值5000ms
return;
}
lastPreemptCheckTime = curTime;
Resource resToPreempt = Resources.clone(Resources.none());
for (FSLeafQueue sched : queueMgr.getLeafQueues()) {
Resources.addTo(resToPreempt, resToPreempt(sched, curTime));//resToPreempt方法是关键,返回队列该抢占的量,为两个Resource对象,内存和cpu相加到resToPreempt,resToPreempt方法返回队列允许的被抢占资源的多少
}
if (Resources.greaterThan(RESOURCE_CALCULATOR, clusterResource, resToPreempt,
Resources.none())) { 最后调用的是DefaultResourceCalculator里的compare方法,用resToPreempt内存减Resources.none内存
preemptResources(resToPreempt); //抢占资源方法
}
}
private boolean shouldAttemptPreemption() {
if (preemptionEnabled) {
return (preemptionUtilizationThreshold < Math.max(