/** * Retrieves, but does not remove, the first allocated container on the specified host. * * @param host the host for which a container is needed. * @return the first {@link Container} allocated for the specified host or {@code null} if there * isn't one. */ protected Container peekAllocatedContainer(String host) { List<Container> allocatedContainers = containerRequestState.getContainersOnAHost(host); if (allocatedContainers == null || allocatedContainers.isEmpty()) { return null; } return allocatedContainers.get(0); }
/** * Method to request a container resource from yarn * * @param expectedContainerId Identifier of the container that will be run when a container * resource is allocated for this request * @param preferredHost Name of the host that you prefer to run the container on */ public final void requestContainer(int expectedContainerId, String preferredHost) { SamzaContainerRequest request = new SamzaContainerRequest( containerMaxMemoryMb, containerMaxCpuCore, DEFAULT_PRIORITY, expectedContainerId, preferredHost); containerRequestState.updateRequestState(request); containerUtil.incrementContainerRequests(); }
/** * Updates the request state and runs the container on the specified host. Assumes a container is * available on the preferred host, so the caller must verify that before invoking this method. * * @param request the {@link SamzaContainerRequest} which is being handled. * @param preferredHost the preferred host on which the container should be run or {@link * ContainerRequestState#ANY_HOST} if there is no host preference. */ protected void runContainer(SamzaContainerRequest request, String preferredHost) { // Get the available container Container container = peekAllocatedContainer(preferredHost); if (container == null) throw new SamzaException("Expected container was unavailable on host " + preferredHost); // Update state containerRequestState.updateStateAfterAssignment(request, preferredHost, container); int expectedContainerId = request.expectedContainerId; // Cancel request and run container log.info( "Found available containers on {}. Assigning request for container_id {} with " + "timestamp {} to container {}", new Object[] { preferredHost, String.valueOf(expectedContainerId), request.getRequestTimestamp(), container.getId() }); try { if (preferredHost.equals(ANY_HOST)) { containerUtil.runContainer(expectedContainerId, container); } else { containerUtil.runMatchedContainer(expectedContainerId, container); } } catch (SamzaContainerLaunchException e) { log.warn( String.format( "Got exception while starting container %s. Requesting a new container on any host", container), e); containerRequestState.releaseUnstartableContainer(container); requestContainer(expectedContainerId, ContainerAllocator.ANY_HOST); } }
/** * Continuously assigns requested containers to the allocated containers provided by the cluster * manager. The loop frequency is governed by thread sleeps for ALLOCATOR_SLEEP_TIME ms. * * <p>Terminates when the isRunning flag is cleared. */ @Override public void run() { while (isRunning.get()) { try { assignContainerRequests(); // Release extra containers and update the entire system's state containerRequestState.releaseExtraContainers(); Thread.sleep(ALLOCATOR_SLEEP_TIME); } catch (InterruptedException e) { log.info("Got InterruptedException in AllocatorThread.", e); } catch (Exception e) { log.error("Got unknown Exception in AllocatorThread.", e); } } }
/** * Method that adds allocated container to a synchronized buffer of allocated containers list See * allocatedContainers in {@link org.apache.samza.job.yarn.ContainerRequestState} * * @param container Container resource returned by the RM */ public final void addContainer(Container container) { containerRequestState.addContainer(container); }
/** * Retrieves, but does not remove, the next pending request in the queue. * * @return the pending request or {@code null} if there is no pending request. */ protected SamzaContainerRequest peekPendingRequest() { return containerRequestState.getRequestsQueue().peek(); }