Yarn capacity scheduler

  • 首先要知道, [Attention: RM有两个组件,其中Scheduler完全就只是负责资源的分配;ApplicationsManager则负责接受application,选取ApplicationMaster,监控重启AM。]
  • CapacityScheduler的优点就是灵活,集群的利用率高;缺点也是由其灵活性造成的,因为CapacityScheduler不支持抢占式调度,必须等上一个任务主动释放资源。
  • 可以看出,只要提交的app数没有达到上限,就能够一直提交app到集群,只是这些app会处于accepted的状态,一直pending,直到ResourceManager给它分配资源。
  • 因此Scheduler实际上是会不断地schedule,然后分配资源给那些集群,在具体分配的时候,在queue内部可能会考虑优先级,然后结合FIFO。

AsyncScheduleThread

  • 在CapacityScheduler内部有个AsyncScheduleThread 这个异步Scheduler线程会不断地调schedule(cs)方法。

schedule(cs)

  • // Schedule on all nodes by starting at a random point.
  • static void schedule(CapacityScheduler cs) 
    • // first randomize the start point
    • Collection<FiCaSchedulerNode> nodes = cs.getAllNodes().values()    // get all the nodes in the cluster
    • for each node: cs.allocateContainersToNode(node)
      • // assign new containers...  1. check for reserved apps(for reservation see here and here. )   2. schedule if there are no reservations
      • if reservedContainer != null
        • get the reserved apps according to reservedContainers
        • // try to fulfill the reservation
        • LeafQueue queue = ((LeafQueue) reservedApplication.getQueue();
        • CSAssignment assignment = queue.assignContainers(clusterResource, node, false); // assignContainers(Resource clusterResource, FiCaSchedulerNode node, boolean needToUnreserve);
          • // if our queue cannot access this node, just return
          • // check for reserved resources
        • TBD...
      • // try to schedule more if there are no reservations to fulfill
      • if (node.getReservedContainer() == null)
        • if (calculator.computeAvailableContainers(node.getAvailableResource(), minimumAllocation) > 0), then  // computeAvailableContainers(Resource available, Resource required), as for DominantResourceCalculator, return the min ratio of mem & vcores.

          • assignContainers(clusterResource, node, false)   // assignContainers(Resource clusterResource, FiCaSchedulerNode node)

            • // if our queue cannot access this node, just return
            • // check for reserved resources    // TBD...
            • // try to assign containers to apps in order
            • for (FoCaSchedulerApp application: activeApplications) 
              • if (SchedulerAppUtils.isBlacklisted(application, node, LOG) // check if this resource is on blacklist, i.e. cannot run the app in this node/rack
              • // schedule in priority order, this is the priority of the resourceRequest of this app
              • for (Priority priority : application.getPriorities())
                • ResourceRequest anyRequest = application.getResourceRequest(priority, ResourceRequest.ANY)
                • Resource required = anyRequest.getCapacity()
                • Set<String> requestedNodeLabels = getRequestLabelSetByExpression(anyRequest.getNodeLabelExpression());
                • // compute user-limit & set headroom.
                • Resource userLimit = computeUserLimitAndSetHeadroom(application, clusterResource, required, requestedNodeLabels)
                  • // compute user limit respect requested labels
                  • // TODO: need consider headroom respect labels also
                  • Resource userLimit = computeUserLimit(application, clusterResource, required, queueUser, requestedLabels)
                    • // our current capacity: equal to the max(required, queue-capacity) if we're running below capacity, equal to (usedResources + required) if running over capacity.
                    • // if we have labels to request(choose to use the first one).
                    • // else if no label on request, just use absolute capacity as capacity for nodes without label.
                    • // TBD...
                • // max avail capacity needs to take into account usage by ancestor-siblings which are greater than their base
                • // calculate absoluteMaxAvailCapacity: my max avail is min(my max capacity, unused from my parent by my siblings if they are beyond their base capacity)
                • // then calculate queueMaxCap using absoluteMaxAvailCapacity
                • // check canAssignToThisQueue
                  • // consider the intersection of queue-canAccessLabels and node-labels, if any of the label beyond queue limit, we cannot allocate on this node.
                  • // check user limit
                  • application.addSchedulingOpportunity(priority);
                  • // try to schedule...
                  • TBD...
  • FYI:
    /** 
    * Headroom is:
    * min(
    * min(userLimit, queueMaxCap) - userConsumed,
    * queueMaxCap - queueUsedResources
    * )
    *
    * ( which can be expressed as,
    * min (userLimit - userConsumed, queuMaxCap - userConsumed,
    * queueMaxCap - queueUsedResources)
    * )
    *
    * given that queueUsedResources >= userConsumed, this simplifies to
    *
    * >> min (userlimit - userConsumed, queueMaxCap - queueUsedResources) <<
    *
    */

addApplication

首先在CapacityScheduler随意找了个方法

synchronized addApplication(ApplicationAttemptedId applicationAttemptId, String queueName, String user)

  • sanity check

    • queue == null
    • !queue instanceof LeafQueue
  • Represents an application from the viewpoint of the scheduler. (Each running app in the RM corresponds to one instance of the FiCaScheduler class)
    • FiCaSchedulerApp SchedulerApp = new FiCaSchedulerApp(applicationAttemptId, user, queue, queue.getActiveUserManager(), rmContext);

      • ActiveUsersManager tracks users in the system. (An active user is defined as someone with outstanding resource requests.)
      • rmContext is the context of the RM.
  • submit to the queue
    • try: queue.submitApplication(SchedulerApp, user, queueName)

      • check queue ACLs
      • synchronized(this) 
        • check if the queue is accepting jobs: if (getState() != QueueState.RUNNING) throw Exception
        • check submission limits for queues:
          • if (getNumApplications() >= getMaxApplications()) throw Exception
        • check submission limits for the user on this queue
        • addApplication(applictaion, user)
          • user.submitApplication() : pendingApp ++; // accepted
          • activateApplications():
            • for each pending apps:

              • check queue limit & user limit again (same as above)
              • activateApplication(): --pendingApp; ++activeApp;
      • metrics.submitApp(userName, attempId): // each queue has a metrics which is an instance of QueueMetrics
        • update metrics: appsSubmitted, appsFailed, appsPending
        • if (parent != null) parent.submitApp(user, attemptId)   // to inform the parents recursively

以上,可以看到在addApplication方法内主要是判断了ACL和appNum的上限,没有resource相关的分配和判断。资源(container)的分配是由相应的applicationMaster向Resourcemanager统一请求的。ResourceRequest使用protobuf。

  • 用户提交应用程序 --> ResourceManager   --> ACL等检查 -->  app accepted.
  • 一旦Scheduler有足够的资源可以满足需求  -->  app由accepted转成running  -->  RM为ApplicationMaster分配一个container,并负责在节点上拉起它。
  • AM是每个用户作业的主进程,负责管理作业生命周期,包括动态地增加or减少资源(container),管理执行流程,处理故障和计算偏差。

Yarn Queues

<Yarn> <Capacity Scheduler> <Source Code>的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. scrapy-redis(一)

    安装scrapy-redis pip install scrapy-redis 从GitHub 上拷贝源码: clone github scrapy-redis源码文件 git clone https ...

  2. MySql习题和答案

    MySQL测试题 一.表关系请创建如下表,并创建相关约束 二.操作表 1.自行创建测试数据 2.查询“生物”课程比“物理”课程成绩高的所有学生的学号.ps:针对的是自己的生物成绩比物理成绩高,再把符合 ...

  3. 《高性能SQL调优精要与案例解析》新书样章

    该书样章已上传,需要的同学可以通过如下地址下载:http://www.itpub.net/thread-2091839-1-1.html http://www.itpub.net/thread-209 ...

  4. telnet限制用户连接数(CentOS)

    一.配置方法 编缉/etc/xinetd.d/telnet在大括号内追加: cps = instances = per_source = 保存然后使用service xinetd restart重启x ...

  5. /etc/profile、~/.bash_profile、~/.bashrc和/etc/bashrc

    文件 引用关系 执行时间 影响用户 使用场景 /etc/profile   开机执行 所有用户 所有用户.重启生效 ~/.bash_profile 引用~/.bashrc 用户登录时执行 当前用户 当 ...

  6. view的clickable属性和点击background颜色改变

    drawable可以是color(color只能是color) android:background=drawable或者color 当一个view(iamge/text view都可以)的andro ...

  7. Struts 2 初步入门(三)

    接Struts 2初步入门(二) 若想用多个通配符设定访问: <struts> <package name="default" namespace="/ ...

  8. linux下文件内容查找 转

    find | xargs grep test find命令和xargs命令 网友:wuye_chinaunix 发布于: : (共有条评论) 查看评论 | 我要评论 青云 分配文件 - -| 回首页 ...

  9. matlab中高维数组怎么做PCA?

    PCA需要先求数据的散布矩阵x*x',再求其特征向量,那么随便一个400*450的图像,就是180000维,矩阵就是180000*180000,matlab无法容纳,那么通常的PCA对图像的降维,比如 ...

  10. linux下stat命令详解

    在linux系统下,使用stat(显示inode信息)命令可以查看一个文件的某些信息,我们先来尝试一下.  简单的介绍一下stat命令显示出来的文件其他信息: - File:显示文件名 - Size: ...