use of org.apache.tez.serviceplugins.api.TaskSchedulerContext.AMState in project tez by apache.
the class DagAwareYarnTaskScheduler method onContainersAllocated.
@Override
public void onContainersAllocated(List<Container> containers) {
AMState appState = getContext().getAMState();
if (stopRequested || appState == AMState.COMPLETED) {
LOG.info("Ignoring {} allocations since app is terminating", containers.size());
for (Container c : containers) {
client.releaseAssignedContainer(c.getId());
}
return;
}
List<Assignment> assignments = assignNewContainers(containers, getContext().getAMState(), getContext().isSession());
informAppAboutAssignments(assignments);
}
use of org.apache.tez.serviceplugins.api.TaskSchedulerContext.AMState in project tez by apache.
the class YarnTaskSchedulerService method assignDelayedContainer.
/**
* Try to assign a re-used container
* @param heldContainer Container to be used to assign to tasks
* @return Assigned container map
*/
private synchronized Map<CookieContainerRequest, Container> assignDelayedContainer(HeldContainer heldContainer) {
AMState state = getContext().getAMState();
boolean isNew = heldContainer.isNew();
if (LOG.isDebugEnabled()) {
LOG.debug("Trying to assign a delayed container" + ", containerId=" + heldContainer.getContainer().getId() + ", nextScheduleTime=" + heldContainer.getNextScheduleTime() + ", containerExpiryTime=" + heldContainer.getContainerExpiryTime() + ", AMState=" + state + ", matchLevel=" + heldContainer.getLocalityMatchLevel() + ", taskRequestsCount=" + taskRequests.size() + ", heldContainers=" + heldContainers.size() + ", delayedContainers=" + delayedContainerManager.delayedContainers.size() + ", isNew=" + isNew);
}
if (state.equals(AMState.IDLE) || taskRequests.isEmpty()) {
// Compute min held containers.
if (getContext().isSession() && sessionNumMinHeldContainers > 0 && sessionMinHeldContainers.isEmpty()) {
// session mode and need to hold onto containers and not done so already
determineMinHeldContainers();
}
heldContainer.resetLocalityMatchLevel();
long currentTime = System.currentTimeMillis();
boolean releaseContainer = false;
if (isNew || (heldContainer.getContainerExpiryTime() <= currentTime && idleContainerTimeoutMin != -1)) {
// new container is possibly a spurious race condition allocation.
if (getContext().isSession() && sessionMinHeldContainers.contains(heldContainer.getContainer().getId())) {
// There are no outstanding requests. So its safe to hold new containers.
// We may have received more containers than necessary and some are unused
// In session mode and container in set of chosen min held containers
// increase the idle container expire time to maintain sanity with
// the rest of the code.
heldContainer.setContainerExpiryTime(getHeldContainerExpireTime(currentTime));
} else {
releaseContainer = true;
}
}
if (releaseContainer) {
LOG.info("No taskRequests. Container's idle timeout delay expired or is new. " + "Releasing container" + ", containerId=" + heldContainer.getContainer().getId() + ", containerExpiryTime=" + heldContainer.getContainerExpiryTime() + ", idleTimeout=" + idleContainerTimeoutMin + ", taskRequestsCount=" + taskRequests.size() + ", heldContainers=" + heldContainers.size() + ", delayedContainers=" + delayedContainerManager.delayedContainers.size() + ", isNew=" + isNew);
releaseUnassignedContainers(Collections.singletonList((heldContainer.getContainer())));
} else {
// no outstanding work and container idle timeout not expired
if (LOG.isDebugEnabled()) {
LOG.debug("Holding onto idle container with no work. CId: " + heldContainer.getContainer().getId() + " with expiry: " + heldContainer.getContainerExpiryTime() + " currentTime: " + currentTime + " next look: " + (currentTime + localitySchedulingDelay));
}
// put back and wait for new requests until expiry
heldContainer.resetLocalityMatchLevel();
delayedContainerManager.addDelayedContainer(heldContainer.getContainer(), currentTime + localitySchedulingDelay);
}
} else if (state.equals(AMState.RUNNING_APP)) {
// clear min held containers since we need to allocate to tasks
if (!sessionMinHeldContainers.isEmpty()) {
// update the expire time of min held containers so that they are
// not released immediately, when new requests come in, if they come in
// just before these containers are about to expire (race condition)
long currentTime = System.currentTimeMillis();
for (ContainerId minHeldCId : sessionMinHeldContainers) {
HeldContainer minHeldContainer = heldContainers.get(minHeldCId);
if (minHeldContainer != null) {
// check in case it got removed because of external reasons
minHeldContainer.setContainerExpiryTime(getHeldContainerExpireTime(currentTime));
}
}
sessionMinHeldContainers.clear();
}
HeldContainer.LocalityMatchLevel localityMatchLevel = heldContainer.getLocalityMatchLevel();
Map<CookieContainerRequest, Container> assignedContainers = new HashMap<CookieContainerRequest, Container>();
Container containerToAssign = heldContainer.container;
heldContainer.incrementAssignmentAttempts();
// always try node local matches for other levels
if (isNew || localityMatchLevel.equals(HeldContainer.LocalityMatchLevel.NEW) || localityMatchLevel.equals(HeldContainer.LocalityMatchLevel.NODE) || localityMatchLevel.equals(HeldContainer.LocalityMatchLevel.RACK) || localityMatchLevel.equals(HeldContainer.LocalityMatchLevel.NON_LOCAL)) {
assignReUsedContainerWithLocation(containerToAssign, NODE_LOCAL_ASSIGNER, assignedContainers, true);
if (LOG.isDebugEnabled() && assignedContainers.isEmpty()) {
LOG.debug("Failed to assign tasks to delayed container using node" + ", containerId=" + heldContainer.getContainer().getId());
}
}
// if scheduling delay is 0, match at RACK allowed without a sleep
if (assignedContainers.isEmpty()) {
if ((reuseRackLocal || isNew) && (localitySchedulingDelay == 0 || (localityMatchLevel.equals(HeldContainer.LocalityMatchLevel.RACK) || localityMatchLevel.equals(HeldContainer.LocalityMatchLevel.NON_LOCAL)))) {
assignReUsedContainerWithLocation(containerToAssign, RACK_LOCAL_ASSIGNER, assignedContainers, false);
if (LOG.isDebugEnabled() && assignedContainers.isEmpty()) {
LOG.debug("Failed to assign tasks to delayed container using rack" + ", containerId=" + heldContainer.getContainer().getId());
}
}
}
// if scheduling delay is 0, match at NON-LOCAL allowed without a sleep
if (assignedContainers.isEmpty()) {
if ((reuseNonLocal || isNew) && (localitySchedulingDelay == 0 || localityMatchLevel.equals(HeldContainer.LocalityMatchLevel.NON_LOCAL))) {
assignReUsedContainerWithLocation(containerToAssign, NON_LOCAL_ASSIGNER, assignedContainers, false);
if (LOG.isDebugEnabled() && assignedContainers.isEmpty()) {
LOG.debug("Failed to assign tasks to delayed container using non-local" + ", containerId=" + heldContainer.getContainer().getId());
}
}
}
if (assignedContainers.isEmpty()) {
long currentTime = System.currentTimeMillis();
// get new containers from YARN to match the pending request
if (!isNew && heldContainer.getContainerExpiryTime() <= currentTime && idleContainerTimeoutMin != -1) {
LOG.info("Container's idle timeout expired. Releasing container" + ", containerId=" + heldContainer.container.getId() + ", containerExpiryTime=" + heldContainer.getContainerExpiryTime() + ", idleTimeoutMin=" + idleContainerTimeoutMin);
releaseUnassignedContainers(Lists.newArrayList(heldContainer.container));
} else {
// Let's decide if this container has hit the end of the road
// EOL true if container's match level is NON-LOCAL
boolean hitFinalMatchLevel = localityMatchLevel.equals(HeldContainer.LocalityMatchLevel.NON_LOCAL);
if (!hitFinalMatchLevel) {
// EOL also true if locality delay is 0
// or rack-local or non-local is disabled
heldContainer.incrementLocalityMatchLevel();
if (localitySchedulingDelay == 0 || (!reuseRackLocal || (!reuseNonLocal && heldContainer.getLocalityMatchLevel().equals(HeldContainer.LocalityMatchLevel.NON_LOCAL)))) {
hitFinalMatchLevel = true;
}
// be short-circuited
if (localitySchedulingDelay > 0 && isNew) {
hitFinalMatchLevel = false;
}
}
if (hitFinalMatchLevel) {
boolean safeToRelease = true;
Priority topPendingPriority = amRmClient.getTopPriority();
Priority containerPriority = heldContainer.container.getPriority();
if (isNew && topPendingPriority != null && containerPriority.compareTo(topPendingPriority) < 0) {
// this container is of lower priority and given to us by the RM for
// a task that will be matched after the current top priority. Keep
// this container for those pending tasks since the RM is not going
// to give this container to us again
safeToRelease = false;
}
// release if there are tasks or this is not a session
if (safeToRelease && (!taskRequests.isEmpty() || !getContext().isSession())) {
LOG.info("Releasing held container as either there are pending but " + " unmatched requests or this is not a session" + ", containerId=" + heldContainer.container.getId() + ", pendingTasks=" + taskRequests.size() + ", isSession=" + getContext().isSession() + ". isNew=" + isNew);
releaseUnassignedContainers(Lists.newArrayList(heldContainer.container));
} else {
// if no tasks, treat this like an idle session
heldContainer.resetLocalityMatchLevel();
delayedContainerManager.addDelayedContainer(heldContainer.getContainer(), currentTime + localitySchedulingDelay);
}
} else {
// Schedule delay container to match at a later try
delayedContainerManager.addDelayedContainer(heldContainer.getContainer(), currentTime + localitySchedulingDelay);
}
}
} else if (LOG.isDebugEnabled()) {
LOG.debug("Delayed container assignment successful" + ", containerId=" + heldContainer.getContainer().getId());
}
return assignedContainers;
} else {
// ignore all other cases?
LOG.warn("Received a request to assign re-used containers when AM was " + " in state: " + state + ". Ignoring request and releasing container" + ": " + heldContainer.getContainer().getId());
releaseUnassignedContainers(Lists.newArrayList(heldContainer.container));
}
return null;
}
use of org.apache.tez.serviceplugins.api.TaskSchedulerContext.AMState in project tez by apache.
the class DagAwareYarnTaskScheduler method deallocateTask.
@Override
public boolean deallocateTask(Object task, boolean taskSucceeded, TaskAttemptEndReason endReason, String diagnostics) {
ContainerId releasedLaunchedContainer = null;
AMState appState = getContext().getAMState();
boolean isSession = getContext().isSession();
TaskRequest newAssignment = null;
HeldContainer hc;
synchronized (this) {
TaskRequest request = removeTaskRequest(task);
if (request != null) {
LOG.debug("Deallocating task {} before it was allocated", task);
return false;
}
hc = removeTaskAssignment(task);
if (hc != null) {
if (taskSucceeded && shouldReuseContainers) {
idleTracker.add(hc);
newAssignment = tryAssignReuseContainer(hc, appState, isSession);
if (newAssignment == null && hc.isReleasedAndUsed()) {
releasedLaunchedContainer = hc.getId();
}
} else {
if (releaseContainer(hc)) {
releasedLaunchedContainer = hc.getId();
}
}
}
}
// perform app callback outside of locks
if (newAssignment != null) {
informAppAboutAssignment(newAssignment, hc.getContainer());
return true;
}
if (releasedLaunchedContainer != null) {
getContext().containerBeingReleased(releasedLaunchedContainer);
return true;
}
return hc != null;
}
Aggregations