Example usage for org.apache.hadoop.yarn.api.records Priority equals

List of usage examples for org.apache.hadoop.yarn.api.records Priority equals

Introduction

In this page you can find the example usage for org.apache.hadoop.yarn.api.records Priority equals.

Prototype

@Override
    public boolean equals(Object obj) 

Source Link

Usage

From source file:org.apache.tez.dag.app.rm.YarnTaskSchedulerService.java

License:Apache License

void preemptIfNeeded() {
    if (preemptionPercentage == 0) {
        // turned off
        return;/*w  w  w .j a v  a 2s. c  o m*/
    }
    ContainerId[] preemptedContainers = null;
    int numPendingRequestsToService = 0;
    synchronized (this) {
        Resource freeResources = amRmClient.getAvailableResources();
        if (LOG.isDebugEnabled()) {
            LOG.debug("Allocated resource memory: " + allocatedResources.getMemory() + " cpu:"
                    + allocatedResources.getVirtualCores() + " delayedContainers: "
                    + delayedContainerManager.delayedContainers.size() + " heartbeats: " + numHeartbeats
                    + " lastPreemptionHeartbeat: " + heartbeatAtLastPreemption);
        }
        assert freeResources.getMemory() >= 0;

        CookieContainerRequest highestPriRequest = null;
        int numHighestPriRequests = 0;
        for (CookieContainerRequest request : taskRequests.values()) {
            if (highestPriRequest == null) {
                highestPriRequest = request;
                numHighestPriRequests = 1;
            } else if (isHigherPriority(request.getPriority(), highestPriRequest.getPriority())) {
                highestPriRequest = request;
                numHighestPriRequests = 1;
            } else if (request.getPriority().equals(highestPriRequest.getPriority())) {
                numHighestPriRequests++;
            }
        }

        if (highestPriRequest == null) {
            // nothing pending
            return;
        }

        if (fitsIn(highestPriRequest.getCapability(), freeResources)) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Highest pri request: " + highestPriRequest + " fits in available resources "
                        + freeResources);
            }
            return;
        }
        // highest priority request will not fit in existing free resources
        // free up some more
        // TODO this is subject to error wrt RM resource normalization

        numPendingRequestsToService = scaleDownByPreemptionPercentage(numHighestPriRequests,
                preemptionPercentage);

        if (numPendingRequestsToService < 1) {
            return;
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("Trying to service " + numPendingRequestsToService + " out of total "
                    + numHighestPriRequests + " pending requests at pri: " + highestPriRequest.getPriority());
        }

        for (int i = 0; i < numPendingRequestsToService; ++i) {
            // This request must have been considered for matching with all existing 
            // containers when request was made.
            Container lowestPriNewContainer = null;
            // could not find anything to preempt. Check if we can release unused 
            // containers
            for (HeldContainer heldContainer : delayedContainerManager.delayedContainers) {
                if (!heldContainer.isNew()) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Reused container exists. Wait for assignment loop to release it. "
                                + heldContainer.getContainer().getId());
                    }
                    return;
                }
                if (heldContainer.geNumAssignmentAttempts() < 3) {
                    // we havent tried to assign this container at node/rack/ANY
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Brand new container. Wait for assignment loop to match it. "
                                + heldContainer.getContainer().getId());
                    }
                    return;
                }
                Container container = heldContainer.getContainer();
                if (lowestPriNewContainer == null
                        || isHigherPriority(lowestPriNewContainer.getPriority(), container.getPriority())) {
                    // there is a lower priority new container
                    lowestPriNewContainer = container;
                }
            }

            if (lowestPriNewContainer != null) {
                LOG.info("Preempting new container: " + lowestPriNewContainer.getId() + " with priority: "
                        + lowestPriNewContainer.getPriority() + " to free resource for request: "
                        + highestPriRequest + " . Current free resources: " + freeResources);
                numPendingRequestsToService--;
                releaseUnassignedContainers(Collections.singletonList(lowestPriNewContainer));
                // We are returning an unused resource back the RM. The RM thinks it 
                // has serviced our initial request and will not re-allocate this back
                // to us anymore. So we need to ask for this again. If there is no
                // outstanding request at that priority then its fine to not ask again.
                // See TEZ-915 for more details
                for (Map.Entry<Object, CookieContainerRequest> entry : taskRequests.entrySet()) {
                    Object task = entry.getKey();
                    CookieContainerRequest request = entry.getValue();
                    if (request.getPriority().equals(lowestPriNewContainer.getPriority())) {
                        LOG.info("Resending request for task again: " + task);
                        deallocateTask(task, true);
                        allocateTask(task, request.getCapability(),
                                (request.getNodes() == null ? null
                                        : request.getNodes().toArray(new String[request.getNodes().size()])),
                                (request.getRacks() == null ? null
                                        : request.getRacks().toArray(new String[request.getRacks().size()])),
                                request.getPriority(), request.getCookie().getContainerSignature(),
                                request.getCookie().getAppCookie());
                        break;
                    }
                }
                // come back and free more new containers if needed
                continue;
            }
        }

        if (numPendingRequestsToService < 1) {
            return;
        }

        // there are no reused or new containers to release. try to preempt running containers
        // this assert will be a no-op in production but can help identify 
        // invalid assumptions during testing
        assert delayedContainerManager.delayedContainers.isEmpty();

        if ((numHeartbeats - heartbeatAtLastPreemption) <= numHeartbeatsBetweenPreemptions) {
            return;
        }

        Priority preemptedTaskPriority = null;
        int numEntriesAtPreemptedPriority = 0;
        for (Map.Entry<Object, Container> entry : taskAllocations.entrySet()) {
            HeldContainer heldContainer = heldContainers.get(entry.getValue().getId());
            CookieContainerRequest lastTaskInfo = heldContainer.getLastTaskInfo();
            Priority taskPriority = lastTaskInfo.getPriority();
            Object signature = lastTaskInfo.getCookie().getContainerSignature();
            if (!isHigherPriority(highestPriRequest.getPriority(), taskPriority)) {
                // higher or same priority
                continue;
            }
            if (containerSignatureMatcher.isExactMatch(highestPriRequest.getCookie().getContainerSignature(),
                    signature)) {
                // exact match with different priorities
                continue;
            }
            if (preemptedTaskPriority == null || !isHigherPriority(taskPriority, preemptedTaskPriority)) {
                // keep the lower priority
                if (taskPriority.equals(preemptedTaskPriority)) {
                    numEntriesAtPreemptedPriority++;
                } else {
                    // this is at a lower priority than existing
                    numEntriesAtPreemptedPriority = 1;
                }
                preemptedTaskPriority = taskPriority;
            }
        }
        if (preemptedTaskPriority != null) {
            int newNumPendingRequestsToService = scaleDownByPreemptionPercentage(
                    Math.min(numEntriesAtPreemptedPriority, numHighestPriRequests), preemptionPercentage);
            numPendingRequestsToService = Math.min(newNumPendingRequestsToService, numPendingRequestsToService);
            if (numPendingRequestsToService < 1) {
                return;
            }
            LOG.info("Trying to service " + numPendingRequestsToService + " out of total "
                    + numHighestPriRequests + " pending requests at pri: " + highestPriRequest.getPriority()
                    + " by preempting from " + numEntriesAtPreemptedPriority + " running tasks at priority: "
                    + preemptedTaskPriority);
            // found something to preempt. get others of the same priority
            preemptedContainers = new ContainerId[numPendingRequestsToService];
            int currIndex = 0;
            for (Map.Entry<Object, Container> entry : taskAllocations.entrySet()) {
                HeldContainer heldContainer = heldContainers.get(entry.getValue().getId());
                CookieContainerRequest lastTaskInfo = heldContainer.getLastTaskInfo();
                Priority taskPriority = lastTaskInfo.getPriority();
                Container container = entry.getValue();
                if (preemptedTaskPriority.equals(taskPriority)) {
                    // taskAllocations map will iterate from oldest to newest assigned containers
                    // keep the N newest containersIds with the matching priority
                    preemptedContainers[currIndex++ % numPendingRequestsToService] = container.getId();
                }
            }
            // app client will be notified when after container is killed
            // and we get its completed container status
        }
    }

    // upcall outside locks
    if (preemptedContainers != null) {
        heartbeatAtLastPreemption = numHeartbeats;
        for (int i = 0; i < numPendingRequestsToService; ++i) {
            ContainerId cId = preemptedContainers[i];
            if (cId != null) {
                LOG.info("Preempting container: " + cId + " currently allocated to a task.");
                appClientDelegate.preemptContainer(cId);
            }
        }
    }
}