/// <summary> /// Assign a container to this node to facilitate /// <paramref name="request"/> /// . If node does /// not have enough memory, create a reservation. This is called once we are /// sure the particular request should be facilitated by this node. /// </summary> /// <param name="node">The node to try placing the container on.</param> /// <param name="request">The ResourceRequest we're trying to satisfy.</param> /// <param name="type">The locality of the assignment.</param> /// <param name="reserved">Whether there's already a container reserved for this app on the node. /// </param> /// <returns> /// If an assignment was made, returns the resources allocated to the /// container. If a reservation was made, returns /// FairScheduler.CONTAINER_RESERVED. If no assignment or reservation was /// made, returns an empty resource. /// </returns> private Org.Apache.Hadoop.Yarn.Api.Records.Resource AssignContainer(FSSchedulerNode node, ResourceRequest request, NodeType type, bool reserved) { // How much does this request need? Org.Apache.Hadoop.Yarn.Api.Records.Resource capability = request.GetCapability(); // How much does the node have? Org.Apache.Hadoop.Yarn.Api.Records.Resource available = node.GetAvailableResource (); Container container = null; if (reserved) { container = node.GetReservedContainer().GetContainer(); } else { container = CreateContainer(node, capability, request.GetPriority()); } // Can we allocate a container on this node? if (Resources.FitsIn(capability, available)) { // Inform the application of the new container for this request RMContainer allocatedContainer = Allocate(type, node, request.GetPriority(), request , container); if (allocatedContainer == null) { // Did the application need this resource? if (reserved) { Unreserve(request.GetPriority(), node); } return(Resources.None()); } // If we had previously made a reservation, delete it if (reserved) { Unreserve(request.GetPriority(), node); } // Inform the node node.AllocateContainer(allocatedContainer); // If this container is used to run AM, update the leaf queue's AM usage if (GetLiveContainers().Count == 1 && !GetUnmanagedAM()) { ((FSLeafQueue)GetQueue()).AddAMResourceUsage(container.GetResource()); SetAmRunning(true); } return(container.GetResource()); } else { if (!FairScheduler.FitsInMaxShare(((FSLeafQueue)GetQueue()), capability)) { return(Resources.None()); } // The desired container won't fit here, so reserve Reserve(request.GetPriority(), node, container, reserved); return(FairScheduler.ContainerReserved); } }
/// <summary> /// Remove the reservation on /// <paramref name="node"/> /// at the given /// <see cref="Org.Apache.Hadoop.Yarn.Api.Records.Priority"/> /// . /// This dispatches SchedulerNode handlers as well. /// </summary> public virtual void Unreserve(Priority priority, FSSchedulerNode node) { RMContainer rmContainer = node.GetReservedContainer(); UnreserveInternal(priority, node); node.UnreserveResource(this); GetMetrics().UnreserveResource(GetUser(), rmContainer.GetContainer().GetResource( )); }
/// <summary>Helper method to check if the queue should attempt assigning resources</summary> /// <returns>true if check passes (can assign) or false otherwise</returns> protected internal virtual bool AssignContainerPreCheck(FSSchedulerNode node) { if (!Resources.FitsIn(GetResourceUsage(), scheduler.GetAllocationConfiguration(). GetMaxResources(GetName())) || node.GetReservedContainer() != null) { return(false); } return(true); }
/// <summary> /// Called when this application already has an existing reservation on the /// given node. /// </summary> /// <remarks> /// Called when this application already has an existing reservation on the /// given node. Sees whether we can turn the reservation into an allocation. /// Also checks whether the application needs the reservation anymore, and /// releases it if not. /// </remarks> /// <param name="node">Node that the application has an existing reservation on</param> public virtual Org.Apache.Hadoop.Yarn.Api.Records.Resource AssignReservedContainer (FSSchedulerNode node) { RMContainer rmContainer = node.GetReservedContainer(); Priority priority = rmContainer.GetReservedPriority(); // Make sure the application still needs requests at this priority if (GetTotalRequiredResources(priority) == 0) { Unreserve(priority, node); return(Resources.None()); } // Fail early if the reserved container won't fit. // Note that we have an assumption here that there's only one container size // per priority. if (!Resources.FitsIn(node.GetReservedContainer().GetReservedResource(), node.GetAvailableResource ())) { return(Resources.None()); } return(AssignContainer(node, true)); }
/// <summary> /// Reserve a spot for /// <paramref name="container"/> /// on this /// <paramref name="node"/> /// . If /// the container is /// <paramref name="alreadyReserved"/> /// on the node, simply /// update relevant bookeeping. This dispatches ro relevant handlers /// in /// <see cref="FSSchedulerNode"/> /// .. /// </summary> private void Reserve(Priority priority, FSSchedulerNode node, Container container , bool alreadyReserved) { Log.Info("Making reservation: node=" + node.GetNodeName() + " app_id=" + GetApplicationId ()); if (!alreadyReserved) { GetMetrics().ReserveResource(GetUser(), container.GetResource()); RMContainer rmContainer = base.Reserve(node, priority, null, container); node.ReserveResource(this, priority, rmContainer); } else { RMContainer rmContainer = node.GetReservedContainer(); base.Reserve(node, priority, rmContainer, container); node.ReserveResource(this, priority, rmContainer); } }
private Org.Apache.Hadoop.Yarn.Api.Records.Resource AssignContainer(FSSchedulerNode node, bool reserved) { if (Log.IsDebugEnabled()) { Log.Debug("Node offered to app: " + GetName() + " reserved: " + reserved); } ICollection <Priority> prioritiesToTry = (reserved) ? Arrays.AsList(node.GetReservedContainer ().GetReservedPriority()) : GetPriorities(); // For each priority, see if we can schedule a node local, rack local // or off-switch request. Rack of off-switch requests may be delayed // (not scheduled) in order to promote better locality. lock (this) { foreach (Priority priority in prioritiesToTry) { if (GetTotalRequiredResources(priority) <= 0 || !HasContainerForNode(priority, node )) { continue; } AddSchedulingOpportunity(priority); // Check the AM resource usage for the leaf queue if (GetLiveContainers().Count == 0 && !GetUnmanagedAM()) { if (!((FSLeafQueue)GetQueue()).CanRunAppAM(GetAMResource())) { return(Resources.None()); } } ResourceRequest rackLocalRequest = GetResourceRequest(priority, node.GetRackName( )); ResourceRequest localRequest = GetResourceRequest(priority, node.GetNodeName()); if (localRequest != null && !localRequest.GetRelaxLocality()) { Log.Warn("Relax locality off is not supported on local request: " + localRequest); } NodeType allowedLocality; if (scheduler.IsContinuousSchedulingEnabled()) { allowedLocality = GetAllowedLocalityLevelByTime(priority, scheduler.GetNodeLocalityDelayMs (), scheduler.GetRackLocalityDelayMs(), scheduler.GetClock().GetTime()); } else { allowedLocality = GetAllowedLocalityLevel(priority, scheduler.GetNumClusterNodes( ), scheduler.GetNodeLocalityThreshold(), scheduler.GetRackLocalityThreshold()); } if (rackLocalRequest != null && rackLocalRequest.GetNumContainers() != 0 && localRequest != null && localRequest.GetNumContainers() != 0) { return(AssignContainer(node, localRequest, NodeType.NodeLocal, reserved)); } if (rackLocalRequest != null && !rackLocalRequest.GetRelaxLocality()) { continue; } if (rackLocalRequest != null && rackLocalRequest.GetNumContainers() != 0 && (allowedLocality .Equals(NodeType.RackLocal) || allowedLocality.Equals(NodeType.OffSwitch))) { return(AssignContainer(node, rackLocalRequest, NodeType.RackLocal, reserved)); } ResourceRequest offSwitchRequest = GetResourceRequest(priority, ResourceRequest.Any ); if (offSwitchRequest != null && !offSwitchRequest.GetRelaxLocality()) { continue; } if (offSwitchRequest != null && offSwitchRequest.GetNumContainers() != 0) { if (!HasNodeOrRackLocalRequests(priority) || allowedLocality.Equals(NodeType.OffSwitch )) { return(AssignContainer(node, offSwitchRequest, NodeType.OffSwitch, reserved)); } } } } return(Resources.None()); }