/// <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); }
public virtual RMContainer Allocate(NodeType type, FSSchedulerNode node, Priority priority, ResourceRequest request, Container container) { lock (this) { // Update allowed locality level NodeType allowed = allowedLocalityLevel[priority]; if (allowed != null) { if (allowed.Equals(NodeType.OffSwitch) && (type.Equals(NodeType.NodeLocal) || type .Equals(NodeType.RackLocal))) { this.ResetAllowedLocalityLevel(priority, type); } else { if (allowed.Equals(NodeType.RackLocal) && type.Equals(NodeType.NodeLocal)) { this.ResetAllowedLocalityLevel(priority, type); } } } // Required sanity check - AM can call 'allocate' to update resource // request without locking the scheduler, hence we need to check if (GetTotalRequiredResources(priority) <= 0) { return(null); } // Create RMContainer RMContainer rmContainer = new RMContainerImpl(container, GetApplicationAttemptId( ), node.GetNodeID(), appSchedulingInfo.GetUser(), rmContext); // Add it to allContainers list. newlyAllocatedContainers.AddItem(rmContainer); liveContainers[container.GetId()] = rmContainer; // Update consumption and track allocations IList <ResourceRequest> resourceRequestList = appSchedulingInfo.Allocate(type, node , priority, request, container); Resources.AddTo(currentConsumption, container.GetResource()); // Update resource requests related to "request" and store in RMContainer ((RMContainerImpl)rmContainer).SetResourceRequests(resourceRequestList); // Inform the container rmContainer.Handle(new RMContainerEvent(container.GetId(), RMContainerEventType.Start )); if (Log.IsDebugEnabled()) { Log.Debug("allocate: applicationAttemptId=" + container.GetId().GetApplicationAttemptId () + " container=" + container.GetId() + " host=" + container.GetNodeId().GetHost () + " type=" + type); } RMAuditLogger.LogSuccess(GetUser(), RMAuditLogger.AuditConstants.AllocContainer, "SchedulerApp", GetApplicationId(), container.GetId()); return(rmContainer); } }
/// <summary> /// Whether this app has containers requests that could be satisfied on the /// given node, if the node had full space. /// </summary> public virtual bool HasContainerForNode(Priority prio, FSSchedulerNode node) { ResourceRequest anyRequest = GetResourceRequest(prio, ResourceRequest.Any); ResourceRequest rackRequest = GetResourceRequest(prio, node.GetRackName()); ResourceRequest nodeRequest = GetResourceRequest(prio, node.GetNodeName()); return(anyRequest != null && anyRequest.GetNumContainers() > 0 && (anyRequest.GetRelaxLocality () || (rackRequest != null && rackRequest.GetNumContainers() > 0)) && (rackRequest == null || rackRequest.GetRelaxLocality() || (nodeRequest != null && nodeRequest .GetNumContainers() > 0)) && Resources.LessThanOrEqual(ResourceCalculator, null, anyRequest.GetCapability(), node.GetRMNode().GetTotalCapability())); }
/// <summary> /// Create and return a container object reflecting an allocation for the /// given appliction on the given node with the given capability and /// priority. /// </summary> public virtual Container CreateContainer(FSSchedulerNode node, Org.Apache.Hadoop.Yarn.Api.Records.Resource capability, Priority priority) { NodeId nodeId = node.GetRMNode().GetNodeID(); ContainerId containerId = BuilderUtils.NewContainerId(GetApplicationAttemptId(), GetNewContainerId()); // Create the container Container container = BuilderUtils.NewContainer(containerId, nodeId, node.GetRMNode ().GetHttpAddress(), capability, priority, null); return(container); }
public override Org.Apache.Hadoop.Yarn.Api.Records.Resource AssignContainer(FSSchedulerNode node) { Org.Apache.Hadoop.Yarn.Api.Records.Resource assigned = Resources.None(); if (Log.IsDebugEnabled()) { Log.Debug("Node " + node.GetNodeName() + " offered to queue: " + GetName()); } if (!AssignContainerPreCheck(node)) { return(assigned); } IComparer <Schedulable> comparator = policy.GetComparator(); writeLock.Lock(); try { runnableApps.Sort(comparator); } finally { writeLock.Unlock(); } // Release write lock here for better performance and avoiding deadlocks. // runnableApps can be in unsorted state because of this section, // but we can accept it in practice since the probability is low. readLock.Lock(); try { foreach (FSAppAttempt sched in runnableApps) { if (SchedulerAppUtils.IsBlacklisted(sched, node, Log)) { continue; } assigned = sched.AssignContainer(node); if (!assigned.Equals(Resources.None())) { break; } } } finally { readLock.Unlock(); } return(assigned); }
/// <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); } }
public override Org.Apache.Hadoop.Yarn.Api.Records.Resource AssignContainer(FSSchedulerNode node) { Org.Apache.Hadoop.Yarn.Api.Records.Resource assigned = Resources.None(); // If this queue is over its limit, reject if (!AssignContainerPreCheck(node)) { return(assigned); } childQueues.Sort(policy.GetComparator()); foreach (FSQueue child in childQueues) { assigned = child.AssignContainer(node); if (!Resources.Equals(assigned, Resources.None())) { break; } } return(assigned); }
/// <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)); }
private void UnreserveInternal(Priority priority, FSSchedulerNode node) { lock (this) { IDictionary <NodeId, RMContainer> reservedContainers = this.reservedContainers[priority ]; RMContainer reservedContainer = Sharpen.Collections.Remove(reservedContainers, node .GetNodeID()); if (reservedContainers.IsEmpty()) { Sharpen.Collections.Remove(this.reservedContainers, priority); } // Reset the re-reservation count ResetReReservations(priority); Org.Apache.Hadoop.Yarn.Api.Records.Resource resource = reservedContainer.GetContainer ().GetResource(); Resources.SubtractFrom(currentReservation, resource); Log.Info("Application " + GetApplicationId() + " unreserved " + " on node " + node + ", currently has " + reservedContainers.Count + " at priority " + priority + "; currentReservation " + currentReservation); } }
public virtual Org.Apache.Hadoop.Yarn.Api.Records.Resource AssignContainer(FSSchedulerNode node) { return(AssignContainer(node, false)); }
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()); }
public abstract Org.Apache.Hadoop.Yarn.Api.Records.Resource AssignContainer(FSSchedulerNode arg1);