List of usage examples for org.apache.hadoop.yarn.api.records Priority equals
@Override
public boolean equals(Object obj)
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); } } } }