/** * Changed the return type to AllocateResponse which use to hold a reference to AMResponse. * * <p>AMResponse seems to have disappeared in CDH 4.6 * * @param requestedContainers * @param releasedContainers * @return * @throws YarnRemoteException */ public AllocateResponse allocateRequest( List<ResourceRequest> requestedContainers, List<ContainerId> releasedContainers) throws YarnRemoteException { if (amResourceManager == null) throw new IllegalStateException( "Cannot send allocation request before connecting to the resource manager!"); LOG.info( "Sending allocation request" + ", requestedSize=" + requestedContainers.size() + ", releasedSize=" + releasedContainers.size()); for (ResourceRequest req : requestedContainers) LOG.info( "Requesting container, host=" + req.getHostName() + ", amount=" + req.getNumContainers() + ", memory=" + req.getCapability().getMemory() + ", priority=" + req.getPriority().getPriority()); for (ContainerId rel : releasedContainers) LOG.info("Releasing container: " + rel.getId()); AllocateRequest request = Records.newRecord(AllocateRequest.class); request.setResponseId(rmRequestId.incrementAndGet()); request.setApplicationAttemptId(appAttemptId); request.addAllAsks(requestedContainers); request.addAllReleases(releasedContainers); AllocateResponse response = amResourceManager.allocate(request); // response.getAllocatedContainers() LOG.debug( "Got an allocation response, " + ", responseId=" + response.getResponseId() + ", numClusterNodes=" + response.getNumClusterNodes() + ", headroom=" + response.getAvailableResources().getMemory() + ", allocatedSize=" + response.getAllocatedContainers().size() + ", updatedNodes=" + response.getUpdatedNodes().size() + ", reboot=" + response.getReboot() + ", completedSize=" + response.getCompletedContainersStatuses().size()); return response; }
@Test public void testAllcoateRequestWithoutIncrease() { AllocateRequest r = AllocateRequest.newInstance(123, 0f, null, null, null, null); // serde AllocateRequestProto p = ((AllocateRequestPBImpl) r).getProto(); r = new AllocateRequestPBImpl(p); // check value Assert.assertEquals(123, r.getResponseId()); Assert.assertEquals(0, r.getIncreaseRequests().size()); }
@Override protected AllocateResponse doContainerRequest() { List<ResourceRequest> requestedContainers = null; if (allocationDirty.getAndSet(false)) { requestedContainers = createRequests(); } else { requestedContainers = EMPTY; } // add pending containers to be released List<ContainerId> release = new ArrayList<ContainerId>(); ContainerId element = null; while ((element = releaseContainers.poll()) != null) { release.add(element); } if (log.isDebugEnabled()) { log.debug("Requesting containers using " + requestedContainers.size() + " requests."); for (ResourceRequest resourceRequest : requestedContainers) { log.debug( "ResourceRequest: " + resourceRequest + " with count=" + resourceRequest.getNumContainers() + " with hostName=" + resourceRequest.getResourceName()); } log.debug("Releasing containers " + release.size()); for (ContainerId cid : release) { log.debug("Release container=" + cid); } log.debug("Request id will be: " + requestId.get()); } // build the allocation request AllocateRequest request = Records.newRecord(AllocateRequest.class); request.setResponseId(requestId.get()); request.setAskList(requestedContainers); request.setReleaseList(release); request.setProgress(applicationProgress); // do request and return response AllocateResponse allocate = getRmTemplate().allocate(request); requestId.set(allocate.getResponseId()); return allocate; }
@Test public void testAllcoateRequestWithIncrease() { List<ContainerResourceIncreaseRequest> incRequests = new ArrayList<ContainerResourceIncreaseRequest>(); for (int i = 0; i < 3; i++) { incRequests.add( ContainerResourceIncreaseRequest.newInstance(null, Resource.newInstance(0, i))); } AllocateRequest r = AllocateRequest.newInstance(123, 0f, null, null, null, incRequests); // serde AllocateRequestProto p = ((AllocateRequestPBImpl) r).getProto(); r = new AllocateRequestPBImpl(p); // check value Assert.assertEquals(123, r.getResponseId()); Assert.assertEquals(incRequests.size(), r.getIncreaseRequests().size()); for (int i = 0; i < incRequests.size(); i++) { Assert.assertEquals( r.getIncreaseRequests().get(i).getCapability().getVirtualCores(), incRequests.get(i).getCapability().getVirtualCores()); } }
protected AllocateResponse makeRemoteRequest() throws IOException { AllocateRequest allocateRequest = AllocateRequest.newInstance( lastResponseID, super.getApplicationProgress(), new ArrayList<ResourceRequest>(ask), new ArrayList<ContainerId>(release), null); AllocateResponse allocateResponse; try { allocateResponse = scheduler.allocate(allocateRequest); } catch (YarnException e) { throw new IOException(e); } lastResponseID = allocateResponse.getResponseId(); availableResources = allocateResponse.getAvailableResources(); lastClusterNmCount = clusterNmCount; clusterNmCount = allocateResponse.getNumClusterNodes(); if (ask.size() > 0 || release.size() > 0) { LOG.info( "getResources() for " + applicationId + ":" + " ask=" + ask.size() + " release= " + release.size() + " newContainers=" + allocateResponse.getAllocatedContainers().size() + " finishedContainers=" + allocateResponse.getCompletedContainersStatuses().size() + " resourcelimit=" + availableResources + " knownNMs=" + clusterNmCount); } ask.clear(); release.clear(); return allocateResponse; }
@Override public AllocateResponse allocate(float progressIndicator) throws YarnException, IOException { Preconditions.checkArgument( progressIndicator >= 0, "Progress indicator should not be negative"); AllocateResponse allocateResponse = null; List<ResourceRequest> askList = null; List<ContainerId> releaseList = null; AllocateRequest allocateRequest = null; List<String> blacklistToAdd = new ArrayList<String>(); List<String> blacklistToRemove = new ArrayList<String>(); try { synchronized (this) { askList = new ArrayList<ResourceRequest>(ask.size()); for (ResourceRequest r : ask) { // create a copy of ResourceRequest as we might change it while the // RPC layer is using it to send info across askList.add( ResourceRequest.newInstance( r.getPriority(), r.getResourceName(), r.getCapability(), r.getNumContainers(), r.getRelaxLocality(), r.getNodeLabelExpression())); } releaseList = new ArrayList<ContainerId>(release); // optimistically clear this collection assuming no RPC failure ask.clear(); release.clear(); blacklistToAdd.addAll(blacklistAdditions); blacklistToRemove.addAll(blacklistRemovals); ResourceBlacklistRequest blacklistRequest = (blacklistToAdd != null) || (blacklistToRemove != null) ? ResourceBlacklistRequest.newInstance(blacklistToAdd, blacklistToRemove) : null; allocateRequest = AllocateRequest.newInstance( lastResponseId, progressIndicator, askList, releaseList, blacklistRequest); // clear blacklistAdditions and blacklistRemovals before // unsynchronized part blacklistAdditions.clear(); blacklistRemovals.clear(); } try { allocateResponse = rmClient.allocate(allocateRequest); } catch (ApplicationMasterNotRegisteredException e) { LOG.warn("ApplicationMaster is out of sync with ResourceManager," + " hence resyncing."); synchronized (this) { release.addAll(this.pendingRelease); blacklistAdditions.addAll(this.blacklistedNodes); for (Map<String, TreeMap<Resource, ResourceRequestInfo>> rr : remoteRequestsTable.values()) { for (Map<Resource, ResourceRequestInfo> capabalities : rr.values()) { for (ResourceRequestInfo request : capabalities.values()) { addResourceRequestToAsk(request.remoteRequest); } } } } // re register with RM registerApplicationMaster(); allocateResponse = allocate(progressIndicator); return allocateResponse; } synchronized (this) { // update these on successful RPC clusterNodeCount = allocateResponse.getNumClusterNodes(); lastResponseId = allocateResponse.getResponseId(); clusterAvailableResources = allocateResponse.getAvailableResources(); if (!allocateResponse.getNMTokens().isEmpty()) { populateNMTokens(allocateResponse.getNMTokens()); } if (allocateResponse.getAMRMToken() != null) { updateAMRMToken(allocateResponse.getAMRMToken()); } if (!pendingRelease.isEmpty() && !allocateResponse.getCompletedContainersStatuses().isEmpty()) { removePendingReleaseRequests(allocateResponse.getCompletedContainersStatuses()); } } } finally { // TODO how to differentiate remote yarn exception vs error in rpc if (allocateResponse == null) { // we hit an exception in allocate() // preserve ask and release for next call to allocate() synchronized (this) { release.addAll(releaseList); // requests could have been added or deleted during call to allocate // If requests were added/removed then there is nothing to do since // the ResourceRequest object in ask would have the actual new value. // If ask does not have this ResourceRequest then it was unchanged and // so we can add the value back safely. // This assumes that there will no concurrent calls to allocate() and // so we dont have to worry about ask being changed in the // synchronized block at the beginning of this method. for (ResourceRequest oldAsk : askList) { if (!ask.contains(oldAsk)) { ask.add(oldAsk); } } blacklistAdditions.addAll(blacklistToAdd); blacklistRemovals.addAll(blacklistToRemove); } } } return allocateResponse; }