/**
   * 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;
  }
Esempio n. 2
0
  @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;
  }
Esempio n. 4
0
  @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;
  }