Search in sources :

Example 1 with AMState

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);
}
Also used : Container(org.apache.hadoop.yarn.api.records.Container) AMState(org.apache.tez.serviceplugins.api.TaskSchedulerContext.AMState)

Example 2 with AMState

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;
}
Also used : Container(org.apache.hadoop.yarn.api.records.Container) ContainerId(org.apache.hadoop.yarn.api.records.ContainerId) Priority(org.apache.hadoop.yarn.api.records.Priority) AMState(org.apache.tez.serviceplugins.api.TaskSchedulerContext.AMState) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap)

Example 3 with AMState

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;
}
Also used : ContainerId(org.apache.hadoop.yarn.api.records.ContainerId) AMState(org.apache.tez.serviceplugins.api.TaskSchedulerContext.AMState)

Aggregations

AMState (org.apache.tez.serviceplugins.api.TaskSchedulerContext.AMState)3 Container (org.apache.hadoop.yarn.api.records.Container)2 ContainerId (org.apache.hadoop.yarn.api.records.ContainerId)2 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 Priority (org.apache.hadoop.yarn.api.records.Priority)1