yarn的学习之2-容量调度器和预订系统

本文翻译自  http://hadoop.apache.org/docs/r2.8.0/hadoop-yarn/hadoop-yarn-site/CapacityScheduler.html

和http://hadoop.apache.org/docs/r2.8.0/hadoop-yarn/hadoop-yarn-site/ReservationSystem.html

1、目的

本文主要描述容量调度器,它是一个可拔插的插件,负责为所有的应用按照特定的限制分配资源。

2、概览

cs(译注:为了便于写,把CapacitiesScheduler编写为cs)的目的就是能够让hadoop应用以操作员友好的方式运行,并能够最大化集群的吞吐和利用。

以往,每个组织都有自己私有的计算资源,并且这些资源具有足够的容量来满足不同时段组织的SLA。这通常会导致交叉的平均利用,并会让管理有点不堪重负,因为如果组织多的话,那么集群也会很多。在不同组织之间共享hadoop集群是比较划算的行为,因为不需要创建私有的集群。然后,每个组织都会关心共享的事情,因为大家都担忧其他组织过分使用集群资源。

cs能够让应用共享集群,并保证应用的资源需求(译注:保证各个应用预先分配的资源,例如不会用着用着,然后发生cpu都被其它应用霸占了之类的事情.并不是说能够让每个应用都可以畅快地使用所有的资源)。中心思想就是共享。此外还有一个不一样的好处,某个时刻某个组织可以使用其它其它组织的资源--换言之,组织可以弹性利用资源。

cs提供一系列严格的限制来确保单个的应用/用户/队列无法消费过量的资源。此外,cs对用户或者队列的初始/挂起应用做某种限制,这样可以确保集群的公平和稳定。

cs的首要概念是队列(queues).这些队列由管理员设置,队列可以实现共享集群的共享经济。

为了提供对资源的进一步的控制,和共享的可预见性,cs支持分层队列(译注:原文hierarchical ),确保在其它队列可以利用空闲资源之前,特定组织的队列(包括子队列)可以共享资源,由此特定组织的的应用可以更好地共享空闲资源。

 

译注:

  1. sla,这里并非指hadoop的服务级别授权,而是指“服务级别协议”,具体可以参考http://www.sohu.com/a/111043704_120672  ,但可以简单理解为“需求”
  2. 这个小节的中心思想就是:cs,共享,队列,分层队列,确保

 

3、特性

  • Hierarchical Queues - 分层队列。确保在其它队列可以利用空闲资源之前,特定组织的队列(包括子队列)可以共享资源,由此特定组织的的应用可以更好地共享空闲资源

  • Capacity Guarantees -容量保证。系统分配给队列分配容量的一部分,这部分就归特定队列处置。队列中的应用都可以访问分配给队列的容量。管理员可以为队列配置软限制和可选的硬限制

  • Security -安全。每个队列都有严格的ACLs,acls控制谁可以提交应用到队列中。此外,一个用户不能看/修改其它用户队列的应用。

  • Elasticity - 弹性。任何队列可以利用空闲资源,即使已经超过了自身的限额。

  • Multi-tenancy - 多租户。有各种设置来保证资源不会被独占,大家可以共享。

  • Operability  --可操作

    • 运行时配置 - 队列定义和属性(如容量),ACLS可以在运行时由管理员以安全的方式修改。此外为管理员和用户提供了一个控制台,通过控制台可以查看当前资源的分配。管理员可以在运行时添加队列,但不能删除正在运行的队列。(译注:如果这样,只能先停止应用了或者先停止队列)
    • 释放应用- 管理员可以在运行时stop队列,但正在运行得应用可以一致运行到完成,而新的应用不能加入队列。如果队列处于STOPPED状态,那么就无法添加新应用到队列或者子队列上。这样管理员可以优雅地停止队列.  此外,管理员可以启动正在停止中(STOPPED)的队列.
  • Resource-based Scheduling(基于资源的调度) - 支持资源密集应用(译注:简而言之就是可以不同需求给予不同资源). 目前支持的资源只有内存。

  • Queue Mapping based on User or Group - 基于用户/组的队列映射  。换言之,不同的用户或者组所提到的作业会对应到不同队列,适当程度简化了操作。

  • Priority Scheduling 优先权调度-  不同应用可以按照不同的优先权调度。应用的优先权值越大,优先级越高。目前,应用优先权只支持FIFO策略。译注:应该指的是在先按照优先权排序的情况下,最大优先权的的可以进入FIFO堆栈,但绝对不能插队。

 

4、配置

4.0 使用容量调度器

修改yarn-site.xml

yarn.resourcemanager.scheduler.class    取值  org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler

4.1 配置队列

etc/hadoop/capacity-scheduler.xml 

cs有个预定义的队列root。所有的队列都是这个队列的子队列。

其它队列可以通过yarn.scheduler.capacity.root.queues配置,多个队列以逗号分隔。

使用队列路径来设定队列的层级。队列路径必须是全路径,以root开始,使用点号作为分隔符。

特定的子队列可以使用以下形式定义yarn.scheduler.capacity.<queue-path>.queues。子队列并不继承上级队列的属性,除非有特别说明。

以下是一个例子,有3个顶级子队列a,b,c。a,b有一些子队列:

<property>
  <name>yarn.scheduler.capacity.root.queues</name>
  <value>a,b,c</value>
  <description>The queues at the this level (root is the root queue).
  </description>
</property>

<property>
  <name>yarn.scheduler.capacity.root.a.queues</name>
  <value>a1,a2</value>
  <description>The queues at the this level (root is the root queue).
  </description>
</property>

<property>
  <name>yarn.scheduler.capacity.root.b.queues</name>
  <value>b1,b2,b3</value>
  <description>The queues at the this level (root is the root queue).
  </description>
</property> 

4.2 队列属性

  • 资源分配
属性描述
yarn.scheduler.capacity.<queue-path>.capacity

容量百分比,可以有小数位。但所有队列的和必须是100。但如果系统有空闲资源,队列中的应用实际是可能耗费比限定的份儿跟多的资源,这就是弹性。

yarn.scheduler.capacity.<queue-path>.maximum-capacity

队列允许使用的最大份额百分比。默认-1,就是不允许。

yarn.scheduler.capacity.<queue-path>.minimum-user-limit-percent

队列中用户的资源下限(百分比-但必须是整数)。用户实际使用的资源可能介于两个限制点之间。一个队列可能包含了多个用户的应用,那么如果一个队列有2个提交了应用的用户,

那么可以限制50,3个就是33,3个就是25,诸如此类。如果设置为100(默认),那么就是不做限制,这样占先用。

yarn.scheduler.capacity.<queue-path>.user-limit-factor

定义某个用户可以使用的容量倍数。默认是1,就是队列容量的全部。这个值可以带小数。

译注:这应该是一个<=1的值。

yarn.scheduler.capacity.<queue-path>.maximum-allocation-mb

资源可以管理器分配给容器的最大内存(分配对队列的最大内存)。这个设置会覆盖 yarn.scheduler.maximum-allocation-mb。但必须小于等于集群的最大限额。

yarn.scheduler.capacity.<queue-path>.maximum-allocation-vcores

最大的虚拟核(virtual core).覆盖 yarn.scheduler.maximum-allocation-vcores,但必须小于等于后者。

  •  运行和挂起应用
PropertyDescription

yarn.scheduler.capacity.maximum-applications

yarn.scheduler.capacity.<queue-path>.maximum-applications

系统并发的正在运行和挂起的应用总数,默认是10000.

yarn.scheduler.capacity.<queue-path>.maximum-applications可以覆盖

yarn.scheduler.capacity.maximum-applications的值,但值只能小于等于后者。

取值为整数。

yarn.scheduler.capacity.maximum-am-resource-percent

yarn.scheduler.capacity.<queue-path>.maximum-am-resource-percent

am可以使用的最大资源百分比(用于并发的活动应用)。取值为浮点数,例如0.5,表示50%。

yarn.scheduler.capacity.<queue-path>.maximum-am-resource-percent可以覆盖

yarn.scheduler.capacity.maximum-am-resource-percent,但取值必须小于等于后者。

        译注:每一行,有两个属性

  • 队列管理和权限
PropertyDescription
yarn.scheduler.capacity.<queue-path>.state

设置队列的状态,可以是RUNNING/STOPPED.如果是后者,则队列不能增加新应用,但现有运行得应用可以一致运行到结束。

yarn.scheduler.capacity.root.<queue-path>.acl_submit_applications

队列提交应用权限列表acl--控制谁可以提交应用。如果用户/组有队列(或者升级队里的)acl权限,那么就可以提交应用。

如果没有设定,那么从其上级继承。

yarn.scheduler.capacity.root.<queue-path>.acl_administer_queue

控制谁可以管理队列的应用。

其它方式同上一行属性。

译注:原文没有说如何管理。停止,删除?

      注:这个acl的格式不同于hdfs文件的acl格式。*表示任何人,space表示没有人。对于root队列来说,如果没有设定,默认是*

  • 基于用户/组的队列隐射
PropertyDescription
yarn.scheduler.capacity.queue-mappings

语法

[u or g]:[name]:[queue_name][,next_mapping]*

列表可以多个,之间以逗号分隔。

%user放在[name]部分,表示已经提交应用的用户。

如果队列名称和用户一样,那可以使用%user表示队列。

如果队列名称和用户主组一样,可以使用%primary_group表示队列。

译注:这个语法有点怪异

yarn.scheduler.capacity.queue-mappings-override.enable

定义针对特定用户的队列是否可以被覆盖。默认是false.

译注:没有说明如何覆盖

     例子:

     <property>
        <name>yarn.scheduler.capacity.queue-mappings</name>
       <value>u:user1:queue1,g:group1:queue2,u:%user:%user,u:user2:%primary_group</value>
      <description>
         Here, <user1> is mapped to <queue1>, <group1> is mapped to <queue2>,
         maps users to queues with the same name as user, <user2> is mapped
         to queue name same as <primary group> respectively. The mappings will be
        evaluated from left to right, and the first valid mapping will be used.

        u:%user:%user  ---已经提交应用的用户,映射到和用户名称一样的队列上。

        u:user2:%primary_group --user2提交的应用映射到user2主组名称一样的队列上。        
      </description>
    </property>

     译注:如果用户组并不多,队列也不多,建议还是使用简单的语法,而不要使用带%的,后者有点混,而且还不知道是否会导致异常。

4.3 配置应用优先权

应用优先和FIFO排序策略一起工作。

Default priority for an application can be at cluster level and queue level.

应用的默认优先权可以设定集群或者队列级别。

  • 集群级别 : 定义了整个集群的最大优先权(整数值),具体原因的优先全如果大于它,那么就以集群最大优先权为准。.  $HADOOP_HOME/etc/hadoop/yarn-site.xml 配置了这个值.
PropertyDescription
yarn.cluster.max-application-priority Defines maximum application priority in a cluster.
  • 叶子队列级别 : $HADOOP_HOME/etc/hadoop/capacity-scheduler.xml 可以配置这个叶子级别的。
PropertyDescription
yarn.scheduler.capacity.root.<leaf-queue-path>.default-application-priority Defines default application priority in a leaf queue.

注意: 如果应用移动到不同的队列,其优先权不会改变

4.4 容量调度容器抢占

cs支持容器抢占,就是如果有一些队列使用了超限的资源,那么这些超限的资源是可以被抢走的。

  • yarn-site.xml 的配置
PropertyDescription
yarn.resourcemanager.scheduler.monitor.enable

启用监视程序。默认不启用

译注:应该设置为true

yarn.resourcemanager.scheduler.monitor.policies

监视策略 

默认值是 org.apache.hadoop.yarn.server.resourcemanager.monitor.capacity.ProportionalCapacityPreemptionPolicy

 

如果yarn.resourcemanager.scheduler.monitor.policies的取值是org.apache.hadoop.yarn.server.resourcemanager.monitor.capacity.ProportionalCapacityPreemptionPolicy

  • 那么可以配置一下属性(同样是在yarn-site.xml中)
PropertyDescription
yarn.resourcemanager.monitor.capacity.preemption.observe_only

眼观手不动-不抢也不杀事件。默认是false.

译注:应该设置为true

yarn.resourcemanager.monitor.capacity.preemption.monitoring_interval

监视间隔(轮询/扫描间隔),默认是3000毫秒。

yarn.resourcemanager.monitor.capacity.preemption.max_wait_before_kill

从发出抢占请求到杀掉容器的时间,默认是15000毫秒

yarn.resourcemanager.monitor.capacity.preemption.total_preemption_per_round

一个回合中,抢占的最大的资源百分比。通过控制这个值,就可以限制从集群申请容器的步伐。

在计算总的期望抢占(需求)后,策略会要求总和必须小于=这个值。默认是0.1

译注:这个比率必须乘以100,才是百分比。

yarn.resourcemanager.monitor.capacity.preemption.max_ignored_over_capacity

如果无法抢占那么多,那么可以少抢多少?

这个值积极的一面是可以防止可能无法抢到。

如果这个值比较高,那么可能无法那么快抢到需要的容量。默认是0.1

yarn.resourcemanager.monitor.capacity.preemption.natural_termination_factor

自然终止抢占百分比(差额).

对于一个计算过的抢占, 由于容器自然过期,那么就只会抢占这个比率的差额。

这个确定了几何比率(这个比率和MAX_IGNORED_OVER_CAPACITY有关)。

李I如,如果因子是0.5(就是5%),那么差额就是95%. 那么在 5 * #WAIT_TIME_BEFORE_KILL间隔内,就会申请几乎95%的资源,即使没有自然终止(其它的应用或者容器)。

默认值是0.2(2%)。

译注:这个定义挺奇怪的。

  • capacity-scheduler.xml 中关于已经属于队列的应用容器抢占配置 。
PropertyDescription
yarn.scheduler.capacity.<queue-path>.disable_preemption

是否禁止抢占已经属于队列的应用容器。

仅当以下两个属性设置如下的时候,本属性才启用:

yarn.resourcemanager.scheduler.monitor.enable = true

yarn.resourcemanager.scheduler.monitor.policies = org.apache.hadoop.yarn.server.resourcemanager.monitor.capacity.ProportionalCapacityPreemptionPolicy

如果特定队列没有设定,就从上级队列继承。

默认是false(译注:就是可以抢)

 

  • 保留管理

cs可以通过参数来控制创建,删除,更新和列出预留信息。注意,任何人都可以这么做,只要有权限(自己的可以操纵自己的)。如果有启用预留acl,但又没有定义,那么任何人都可以操作。

在下面这个例子中,<queue>是队列名称。

PropertyDescription
yarn.scheduler.capacity.root.default.acl_administer_reservations 设置默认队列的管理acl
yarn.scheduler.capacity.root.<queue>.acl_administer_reservations

这个ACL具有全部权限:创建,删除,修改和列出。 这个权限不继承上级的,除非有特定说明(译注:如何特别说明)

译注:文档并没有给出acl的示例。但根据本文多次出现过的经验来看,也许是“u:user1:queue1,g:group1:queue2”这样形式的。

yarn.scheduler.capacity.root.<queue>.acl_list_reservations

查看权限。

这个权限不继承上级的,除非有特定说明(译注:如何特别说明)

yarn.scheduler.capacity.root.<queue>.acl_submit_reservations

提交(创建)

这个权限不继承上级的,除非有特定说明(译注:如何特别说明)

  译注:上表的属性中包含了<queue>而不是<queue-path>,当时原文作者的疏忽所致。本人认为,这应该修改为<queue-path>更好,更容易理解,也可以保持全文一致。

4.5 使用容量调度器配置预订系统

cs支持预订系统-允许用户预留资源。

应用可以在运行时(提交)设定 reservationId,以请求保留的资源。

  •  yarn-site.xml 中的配置
PropertyDescription
yarn.resourcemanager.reservation-system.enable

是否启用预订(非空)

默认为否(false)

取值true/false

yarn.resourcemanager.reservation-system.class

预订类(可选)

如果没有设置,就直接取 yarn-site.xml中yarn.resourcemanager.scheduler.class属性值。

译注:cs的话,就取 org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler

yarn.resourcemanager.reservation-system.plan.follower

PlanFollower类名,用于定时同步cs(可选参数)

取值和yarn.resourcemanager.scheduler.class属性值有关。

如果cs,那么取值org.apache.hadoop.yarn.server.resourcemanager.reservation.CapacitySchedulerPlanFollower

yarn.resourcemanager.reservation-system.planfollower.time-step

PlanFollower定时器的间隔(毫秒-整数,可选参数)。

默认是1000毫秒

  • capacity-scheduler.xml中的配置

      cs支持预订,而且可以在任意叶子队列上配置。

PropertyDescription
yarn.scheduler.capacity.<queue-path>.reservable

是否可以预订(非空)

默认false(不可以)

译注:因为设置就是为了预订,所以一般设定为true

yarn.scheduler.capacity.<queue-path>.reservation-agent

预订代理(类名),用于确定预订代理是否已经实现。

默认值:org.apache.hadoop.yarn.server.resourcemanager.reservation.planning.AlignedPlannerWithGreedy.

yarn.scheduler.capacity.<queue-path>.reservation-move-on-expiry

可选参数

当有关的预订过期后,应用是否要移动到上级可预订的队列(或者是被杀掉)

默认是true.

yarn.scheduler.capacity.<queue-path>.show-reservations-as-queues

可选参数

是否在调度器UI中显示预订队列。

默认false(不显示)

yarn.scheduler.capacity.<queue-path>.reservation-policy

预订策略类(可选参数)

用于确定共享策略是否实现了,这个共享策略负责验证新的预订没有破坏标准。

默认值是org.apache.hadoop.yarn.server.resourcemanager.reservation.CapacityOverTimePolicy.

yarn.scheduler.capacity.<queue-path>.reservation-window

预留窗口(可选参数)

单位毫秒(必须是整数)

共享策略类在这个窗口内会验证计划中约束是否通过。

默认是1天(86400000)

yarn.scheduler.capacity.<queue-path>.instantaneous-max-capacity

瞬间最大容量(可选参数)

实际是任意时间,单位是比率(但不是百分比)

共享策略允许单个用户保留的最大容量

默认是1,也就是100%.

yarn.scheduler.capacity.<queue-path>.average-capacity

平均容量(可选参数)

在预订窗口内,共享策略允许单个用户保留的平均容量。

默认是1(100%)

yarn.scheduler.capacity.<queue-path>.reservation-planner

预订计划执行程序(类,可选)

用于确认计划程序的实现情况,如果计划容量低于用于预订的,那么这个类会被激活。

默认值 org.apache.hadoop.yarn.server.resourcemanager.reservation.planning.SimpleCapacityReplanner

这个类被激活后,会扫描计划,并按照LIFO的顺序尽可能地移除预留的容量,直到预留的资源达到了计划要求。

译注:LIFO--即后进先出。

yarn.scheduler.capacity.<queue-path>.reservation-enforcement-window

预留强制窗口(可选)

计划程序在这个时间窗口内,会验证计划限定是否被满足了。

整数类型,单位毫秒

默认是1小时即3600000

  译注:具体如何预订,并不是仅仅这几个参数。实际实现的时候,还需要结合一些其它操作,例如yarn关于rm的REST API  

  也许以后,yarn自己会提供cli工具直接申请预订并提交作业,目前来看,需要通过编程来实现。

  但很多时候,如果不直接使用yarn的话,也不需要考虑这个,例如使用spark,presto的时候,它们可以和yarn一起部署。

  预订系统更多的内容可以参阅 http://hadoop.apache.org/docs/r2.8.0/hadoop-yarn/hadoop-yarn-site/ReservationSystem.html

 

4.6 其它属性

  • 资源计算器
PropertyDescription
yarn.scheduler.capacity.resource-calculator

资源计算器类-比较调度器中的资源。

例如org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator仅仅计算内存,而DominantResourceCalculator会使用内存,cpu等等。

译注:目前还是使用 org.apache.hadoop.yarn.util.resource.DefaultResourceCalculator 吧。

因为有关的实现主要基于内存的。

yarn的资源管理还是比较初级的。

  • 数据本地性
PropertyDescription
yarn.scheduler.capacity.node-locality-delay

节点局部性延迟

在cs企图调度本地机栈容器后(失败),还可以错过错过多少次的调度次数。

通常设置为集群节点数。

默认情况下,应该设置为基站中节点数,例如40(一个机栈可能有40台)。

译注:调度器在本地机栈找资源,可以在机栈内的节点一个个找过去。所以可以尝试那么多次。

由于没有看有关的代码,并不清楚具体如何一个个找的。

4.7 回顾容量调度器配置

一旦按照配置完毕,这些配置可以通过yarn的WEB-UI来查看:

  • 以常规模式启动yarn

  • 打开rm的web-ui

  • 找到 /scheduler 页面,就可以看到队列和有关资源.

5、修改队列配置

修改队列属性,添加队列是非常简单。只需要编辑conf/capacity-scheduler.xml,并执行 yarn rmadmin -refreshQueues

$ vi $HADOOP_CONF_DIR/capacity-scheduler.xml
$ $HADOOP_YARN_HOME/bin/yarn rmadmin -refreshQueues

注意:  队列不能删除,但可以添加新的,更新也是可以的。  

 

译注:不需要修改所有节点上的,因为rmadmin会自动做那个事情。此外如何删除队列?难道要靠重配,重启yarn集群吗?

 

以下内容翻译自 http://hadoop.apache.org/docs/r2.8.0/hadoop-yarn/hadoop-yarn-site/ReservationSystem.html

6、预订系统

译注:本文已经省略掉一些原文的内容

   流程图

  

   典型预订流程:

  • Step 0       用户提交一个预订创建请求,并接收到一个响应,响应包含一个ReservationId(预订ID)
  • Step 1      用户提交一个预订请求(使用 Reservation Definition Language (RDL) --预定定义语言)和预订ID,请求包括诸如资源和暂时约束(例如截止时间)。这个提交可以使用编程方式完成,编程方式包括使用客户端到RM的协议或者RM REST api  。如果相同的RDL内容和预订ID提交做了多次,但是是无用的,系统不会创建新的预留,虽然系统的提示是成功的。如果仅仅RDL不同,那么会被拒绝。

  • Step 2    预订系统启动一个预订代理(ReservationAgent,上图绿色的。译注:原文说绿色,但本文看到的是蓝色的),从PLAN(计划中)找一可用的分配,所谓PLAN(计划)就是一个数据结构,记录了所有已经接收的预订和系统中的可用资源。

  • Step 3    共享策略提供一个途径来强制收到的预留是恒定的(至少是符合要求的),而这个收到的可能是潜在会被拒绝的。 例如,CapacityOvertimePolicy会允许用户的瞬时最大容量,但一段时间内又会做一定的限制 。例如用户的瞬时请求可以是50%的集群容量,但在24小时内,均值不能超过10% 。

  • Step 4   成功验证后,预订系统会返回给用户一个预订ID(可以比作一张车票)

  • Step 5   当预订时间到达,部件PlanFollower(后续计划程序)把计划的状态推送给调度器 ,推送方式是动态创建/ 调整/销毁队列。

  • Step 6   然后用户可以提交一个或者多个作业给预留队列,提交的时候只需要简单地包含预订ID即可。

  • Step 7  调度器会提供一些容器(这些容器已经预先创建,用于满足预订需求)。在预订限制内,用户可以随意使用资源。

  • Step 8 系统包含适应/脱离集群容量的机制。包括如果可能就移动预留,或者拒绝一些最小量的请求

 

 译注:总体上预订的实现分为几个步骤:

      1.预订

      2.执行,包含提交计划和调整共享。

      3.脱离(完结)

 

posted @ 2017-06-28 16:45  正在战斗中  阅读(1142)  评论(0编辑  收藏  举报