Example #1
0
        /// <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);
            }
        }
Example #2
0
        /// <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(
                                               ));
        }
Example #3
0
 /// <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);
 }
Example #4
0
 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);
     }
 }
Example #5
0
        /// <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()));
        }
Example #6
0
        /// <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);
        }
Example #7
0
        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);
        }
Example #8
0
 /// <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);
     }
 }
Example #9
0
 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);
 }
Example #10
0
        /// <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));
        }
Example #11
0
 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);
     }
 }
Example #12
0
 public virtual Org.Apache.Hadoop.Yarn.Api.Records.Resource AssignContainer(FSSchedulerNode
                                                                            node)
 {
     return(AssignContainer(node, false));
 }
Example #13
0
        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());
        }
Example #14
0
 public abstract Org.Apache.Hadoop.Yarn.Api.Records.Resource AssignContainer(FSSchedulerNode
                                                                             arg1);