YARN-2915 yarn联邦设计文档

1. 简介

YARN可以部署到上千个节点上.ResourceManager是限制yarn的扩展性的关键因素.resourcemanager性能越好,能管理的节点数目,活跃作业数目,心跳频率(节点和作业的)越多.降低心跳频率可以提高集群扩展性,但是不利于资源利用.(可以参考hadoop1.x的经验).这篇文档描述了使用基于联邦的方法,将yarn集群扩展到上万个节点.该方法将一个大集群(1-10万个节点)划分成多个子集群,每个子集群有自己的RM和NMs.联邦系统可以整合这些子集群,对应用来说,就像一个单独的大集群一样.运行在这个联邦YARN系统中的应用可以将任务分配到集群中的任意一个节点上.联邦系统会协调各个子集群,可以实现透明地调度一个作业的子任务到各个子集群中.联邦设计在结构上就具有扩展性.每个RM只负责一定数目节点的资源调度,使用特定的调度策略,让大部分的应用在自己所负责的子集群内运行,因此每个RM能够看到的应用数目也是有限的.这意味着我们几乎只要添加子集群(只做少许的额外调整)就可以实现集群的线性扩展.

这种架构可以保证每个子集群内部调度的稳定性.例如,当一个子集群丢失大量的节点时,我们可以重定向队列到其它子集群中,这样可以不影响受损集群上的作业.联邦功能的实现代码是封装在现有yarn代码上的一层代码,对现有YARN的调度机制只做了有限的修改.

限定条件:

   a.子集群之间具有良好的联通性,(例如,联邦尚不打算跨数据中心部署)

   b.HDFS要首先部署好联邦

2.YARN联邦架构

在这一章节我们将讨论联邦里涉及到的高级架构和主要组件.

众所周知,开源软件YARN可以部署到几千个几点上.联邦的概念就是将这些小的YARN集群(子集群)整合成上万个节点的大集群.运行在这个联邦系统中的应用看到的是整个大的集群,并且可以将子任务运行到集群中的任意一个节点上.

  2.1 下图展示了联邦的逻辑架构.

 

  2.1.1 YARN子集群

  一个子集群里最多包含几千个节点.具体的子集群大小要综合具体的环境性能要求,网络延迟,和其它实际经验来确定.子集群要具有高可用性,即可以容忍YARN RM,NM宕机,实现伤害最小化.如果一个子集群整个挂掉,联邦机制应该保证这个子集群上的作业被重新提交到另一个子集群上.在联邦集群里,子集群是一个扩展单位.我们可以通过添加一个或者多个联邦来扩展一个联邦集群.而且,各自独立的子集群可以决定是否并入联邦系统,贡献出自己一部分的资源.

   2.1.2 Router (YARN-3659)

  联邦系统中应用会首先提交到Router上,(Router有多个,具体提交到哪个Router要由路由策略(从Policy store中获取)来决定),然后在State Store中获得sub-cluster的URL,最后将作业提交请求重定向到合适的sub-cluster RM上.一个作业在哪一个子集群中启动,这个子集群就被称为该作业的"home sub-cluster",其它子集群都是该作业的"secondary sub-cluster". Router将ApplicationClientProtocol暴露在最外面一层来隐藏多个RMs的存在.为了实现这一点,Router会将该作业及其home sub-cluster的映射关系保存到State Store当中.这样Routers可以保持soft-state并且更加方便地处理用好请求(可以不需要扫描全部的RMs,就可以将作业定向到正确的RM上).在任何时候,一个作业都可以将任务运行在home sub-cluster和多个secondary sub-cluster,但是我们所提出的策略会限制一个作业尽量在一个子集群中运行,以此来减小调度代价.

  2.1.3AMRMProxy (YARN-3666)

  AMRMProxy是保证应用可以跨子集群运行的关键组件.AMRMProxy会在每个NM上启动,它们实现了ApplicationMasterProtocol,充当AM向YARN RM的代理.应用不允许和子集群中的RM直接通信,它们被联邦系统强制限定只能与AMRMProxy通信,以此来实现多RMs的透明访问.

  2.1.4 Global Policy Generator (GPG) (YARN-3660)

     Global Policy Generator会持续观测整个联邦系统,确保其配置合理性.一个关键的设计点是,集群不要求GPG始终开启.GPG会持续运转,但是独立于所有的集群动作,以此更加能够保证全局稳定性,负载平衡性.GPG可以更加准确地更新用户在子集群上的容量影射表,并且更加准确地更新Routers,AMRMProxy甚至RMS中的策略.当GPG不能工作的时候,集群会按照GPG上一次发布的策略运行.当GPG长期不工作的时候,意味着之前调到最优状态的配置,集群优化利用率和全局稳定性会过期.注意:在当前的设计原型中,GPG是一个只能通过CLI手动调优的过程(YARN-3657).

  2.1.5 Federation State Store (YARN-3662, YARN-3663)

  联邦状态能够帮助将多个小集群整合成一个大集群.这包括如下信息:

  2.1.6 Sub-cluster Membership (YARN-3665)

  RMs会持续不断地向state store汇报心跳,并且发布自己当前的容量和负载信息.GPG会基于这些信息制定合适的调度策略.而且,Routers也可以基于这些信息来选择最优的home-sub-cluster.这种机制允许我们可以动态地添加或者减少一些子集群来调整集群总量,也利于维护每个子集群.这种机制需要YARN RM做出相应的调整,但是不复杂.

  2.1.7 Application’s Home Sub-cluster

  Application Master所运行的集群被称为该AM的home-sub-cluster.AM不仅可以向自己的home-sub-cluster申请资源,也可以向其他子集群申请资源,这些集群被称为secondary sub-clusters.整个联邦系统需要周期性地优化,以保证AM可以在它的home-sub-cluster申请到大部分的资源,只有在极少数的情况下才会向secondary sub cluster申请资源.从最近的测试例子中表明我们需要维护一个单独的"外部APP ID"和"内部APP ID"之间的映射.这样我们可以隐藏一些本地失败(例如,当一个RM挂掉之后,该RM上的作业需要重新提交,并且app id会重新生成)

  2.1.8 Federation Policy Store (YARN-3664, YARN-3663)

  Federation Policy Store是一个逻辑的,单独的store(但是它有可能和其他角色合设),它包含了用户资源的分配信息,用户的home sub-cluster信息和各个组件(Router,AMRMProxy,RMs)使用的调度策略.

  2.1.9 Capacity Allocation across sub-clusters (YARN-3658)

  下面讨论一个重要的问题,如何映射联邦级别的资源分配和子集群的资源分配.有两方面可以考虑:

  1)利用队列的概念将联邦级别的队列和子集群级别的队列映射起来

  2)使用预留资源(Reservations)的概念(YARN-1051),将预留资源和子集群映射起来

  预留资源方法的特点是更加动态化.原因是不同子集群的容量会因节点宕机而变化,为了确保集群稳定性,我们需要增加/减少每个子集群分配给用户/组的资源.预留资源被表示为绝对值,(例如100container是绝对值,而0.2%是相对值),并且具有非常动态的add/remove/resize性能.所以是更加有用的方法.至于跨子集群的队列资源支持仍然是一个开放性问题.注意:本文档谈到的大多数机制虽然给出了原型,但仍然处在探索之中.

  2.2 跨子集群运行应用程序

  当一个应用被提交到联邦系统时,系统会决策哪一个子集群最适合做这个应用的home sub-cluster.AM和RM之间的所有通信都会通过该AM所在主机的AMRMProxy进行.AMRMProxy向外暴露ApplicationMasterService协议来充当YARN RM.AM可以根据从本地存储层获得的本地信息来请求containers.在理想的场景下,应用只要向它的home-sub-cluster请求资源就可以了,但是,如果该应用需要向其他子集群请求资源,AMRMProxy会与那些子集群进行交互,并且为该应用申请资源.因此,应用可以向整个联邦系统请求资源.所有这些透明的操作都是通过协调AMRMProxy,Global Policy Generator (GPG) 和 Router来完成的.下图展示这几个组件之间是如何交互的.

  1. Router接收到一个通过YARN pplication Client Protocol提交的应用请求. 

  2. Router通过查询路由(策略)表来为该应用选择一个"home RM".

       3.  Router访问state store来确定该 home RM 的地址

  4. Router将应用提交请求重定向到 home RM.

  5. Router将包含home RM标识的应用状态信息保存到state store中

  6. 当应用被提交到home RM上时,作业的执行流程就开始了.例如,应用会被提交到调度器队列上,它的AM会在home-sub-cluster上的第一个有足够资源的nodemanager上被启动. 

    a. 在这个过程中,AM的执行环境中会加入AMRMProxy的地址,以便和之后的YARN RM进行通信.

    b. AM的安全令牌也会被修改,这样,AM就只能和AMRMProxy通信.之后AM和RM之间的一切通信都由AMRMProxy来完成.

   7. AM根据HDFS上的本地信息来申请containers

  8. AMRMProxy可以基于某种策略,扮演成AM在其它子集群上启动一个Unmanaged AM,并且向两个子集群同时汇报集群.

  9. AMRMProxy会同时根据本地信息和从GPG获得的调度策略来决定是从home-sub-cluster还是从secondary sub cluster来请求资源.在上图中,AMRMProxy就是决定向secondary sub cluster来请求资源.

  10. Secondary RM为AMRMProxy提供有效的container令牌来在该RM集群上启动一个container.这样一来,每个sub-cluster都可以保证只使用到自己的安全令牌,从而避免需要一个全局的产生令牌的组件

  11. AMRMProxy把资源被分配的响应传回给AM.

  12. AM使用标准的YARN协议在目标NodeManager(在sub-cluster2)上启动container.

  2.2.1 AMRMProxy的作用
  1. 避免YARN RMs受到AMs错误行为的影响.AMRMProxy可以杀死那些申请非常多资源的AM,以此来阻止DDOS攻击.

  2. 隐藏集群中多个RMs,可以透明地实现AM向多个子集群请求资源.所有的资源申请和分配都是通过AMRMProxy向home或者其它子集群申请资源来完成的.

  3. 既然所有应用的资源分配都是AMRMProxy传达的,那么它将处理所有的请求.因为RM不可以处理跨子集群的资源请求.

  4. AMRMProxy可以配置集群负载策略.

       2.2.2 Role of Global Policy Generator (GPG)

  1. 监测整个联邦系统,并维护它.

  2. 为每个帐号在子集群上创建reservations(动态队列)

  3. 为Router服务提供路由策略

  4. 为每个节点上的AMRMProxy创建应用调度策略.

 3. 详细设计

  以上我们从最外一层讨论了各个组件及其职责,而在这一章节我们详细地讨论各个组件和服务的具体实现.

  3.1 Router

  Router是个与状态无关的YARN组件,是整个联邦集群的入口组件.它可以部署在多台机器上,对外暴露一个虚拟IP(VIP).Router实现了整个的ApplicationClientProtocol,用户所有的请求,如请求或更新reservations,提交或者杀死作业,查询作业状态等,都由Router来处理.这其中会涉及到原始请求的分解并传递到子集群的RMs上,把结果汇总返回给用户等.Router的职责包括:

   1)产生全局唯一的应用标识;

   2)基于AMRoutingPolicy确定一个应用的home-sub-cluster

   3)重定向应用提交请求到home-RM,并且把应用和它的home-RM所组成的映射存储到StateStore中.

   4)将关于此应用的后续请求重定向到正确的RM上

   5)应用有可能需要多个子集群上的资源,所以Router可能会向多个RMs广播并整合广播结果,整个过程实现透明访问.

 3.1.1 AM Routing

  下图描述了Router如何通过相应的策略将应用提交请求重定向到子集群上.

  1. Router会在PolicyStore中检索与用户相对应的AMRoutingPolicy和reservation.为了性能优化,Router会缓存所有的策略.

  2. PolicyStore返回分配策略给Router.返回结果是经过序列化的(在这里,我们使用protocol buffer).所以,在返回给Router之前,需要将结果反序列化存储到一个FederationPolicyInstance实例当中.

  3. Router将上一步中的FederationPolicyInstance实例传送到所配置的解释器,并从中获得sub-cluster ID.

  4. Sub-cluster ID 被返回给Router

  5. Router将应用提交请求发送到该sub-cluster上.

  6. Router将该sub-cluster上的任何响应返回给客户端.

  注意: 上图中显示了好几次与StateStore,PolicyStore的往返请求,这其中有很多都可以实现缓存.例如,appication-subcluster的映射可以很容易地保存在Router的持久化设备里.在Router重启时,Router从没见过的应用被提交到这个Router上时,这些应用提交请求可以被提交到它们的子集群上.如果这些缓存的映射过期了,也可以很容易地检测出来(RM可以告诉Router该应用不属于这个子集群),然后将新该应用新的appication-subcluster映射保存到StateStore当中.

  一些制定好的AMRoutingPolicy的例子:

      AMRoutingPolicy可以有很多种,以下是一些例子:

  Simple Priority: 最基本的一种基于优先级的策略.例如一个用户在子集群1,3,4上有预留资源,则该策略将顺序搜索集群1,3,4,当集群1没资源时,会转到集群3,4.

  Simple Weighting: 另一种简单的允许用户申请多个集群资源的策略.例如,用户在子集群1上有预留70个节点,在子集群3上预留20个节点,在子集群4上预留10个节点,则该用户的作业会有70%在子集群1上.

  Load-balancing: 这个策略与Simple Weight策略相似,但是会额外地基于集群资源利用率信息来分配作业.例如,用户在子集群1上用了预留70个节点中的68个,而在集群4用了10个预留节点中的5个,则该用户之后的作业很可能会分配到集群4上.

  3.2 AMRMProxy

   本地ResourceManager代理(也叫AMRMProxy)是运行在每个节点(或每个机架)上的,NodeManager的附属服务.AMRMProxy会暴露ApplicationMasterService协议接口,并且监听请求信息,功能类似于YARN RM.所有该节点上的AM都会首先链接AMRMProxy.

   3.2.1 ResourceRequestRoutingPolicy

   AMRMProxy会基于如下表格来决定何时向Home RM通信,何时向其它子集群通信.

请求中是否指定节点 节点是否在home-cluster 支持本地松弛 AMRMProxyPolicy container位置
检查负载和资源容量并把该请求发送给home RM Home sub cluster
查看该AM是否有访问该子集群的权限,如果有,则在该集群上启动一个unmangered-am并接受请求 Secondary sub cluster
是/否 检查负载和集群容量,并基于容量和权限信息把请求发送给home/secondary RM Home sub cluster
是/否 是/否 根据负载和容量,权限等信息,首先发送请求到home-cluster,无法满足则发送请求到Secondary RMs Home/Secondary sub cluster

            下图是AMRMProxy的内部结构

 AMs总是先连接AMRMProxy来注册应用和发送心跳.AMRMProxy会为每个AM创建提交请求的管道,每个AM都会在AMRMProxy上有一个独立的管道实例.管道也有利于实现添加附加的逻辑策略.例如,以后有可能添加节流请求的模块,资源测量模块,审计模块等等.管道中的最后一个模块负责与真实的YARN RM沟通.因为AM可以请求多个子集群的资源,所以,管道的最后一个模块有可能会有多个Unmanaged AM 实例.

  3.3 State Store

   联邦的整体架构设计依靠一个集中式的持久化组件,这个组件就被称为State Store.该设计遵循持久化最少的状态信息就可以运转整个联邦系统的原则.我们需要使用这些状态信息(当前存储在YARN RM中),在它的基础上来发发送广播请求,返回整合过后的响应信息.在联邦设计中,需要保证使用最小的代价来维护和更新状态信息,每个状态信息都只有一个起源,以此来避免状态信息不一致导致YARN卡死.下面我们介绍一下访问state store的API.

   3.3.1 State Store APIs

   联邦State Store中包含了所有的状态信息,这些信息可以用来整合所有的YARN sub_clusters成一个统一的大的集群.联邦StateStore是由以下逻辑子状态组成的:

           FederationMembershipState:它维护了所有子集群成员的信息,包括每个子集群的资源容量信息,子集群可以是异构的.子集群可以通过FederationMembershipState自由选择是否加入联邦集群.实现这个功能的API有:

    a. registerRouter ():Router会在启动的时候向state store请求一个标识.这个标识在整个联邦系统中是惟一的.这个标识在Router整个生命周期里都是有效的.Router会基于这个标识为每个应用产生唯一的id.

    b. registerSubCluster (): 子集群的RMs通过这个api来向联邦系统注册自己的容量和调度URL.这通常发生在RM的启动或者主备切换阶段.通过这个api,RM可以获得唯一的标识.这个标识是静态的,它不会因为RM重启而销毁.
    c. deregisterSubCluster ():子集群的RMs使用这个api来取消加入联邦集群.这通常在关掉子集群或者进行维护时用到.

    d. subClusterHeartbeat (): 子集群使用此api来周期性地向联邦系统汇报心跳.心跳中包含当前集群容量的信息,这个信息是动态的,因为子集群时刻在调度资源.将来可以加如心跳响应来部署一些特定的调度策略.

    e. getSubClusterInfo ():这个api可以供联邦成员如Router使用,来获得联邦系统内一个特定子集群的信息.信息包括子集群地址,当前容量,以用来指定调度策略.

   FederationApplicationState: 它存储了所有联邦系统上的应用的状态信息.它的api包括:

    a. registerApplication():新应用可以使用它来注册自己的home-sub-cluster.

    b. achiveApplication (): 用来更新state store中应用状态信息的api.

    c. getHomeSubClusterForApp () :这个api返回一个应用的home-sub-cluster.Router使用该api来为用户获得一个子集群的标识,并把用户请求发送到正确的子集群中.

   3.4 Policy Store

  联邦的概念本身只是把一些独立分散的子集群整合一个大的集群.这种整合是基于某种策略的.这种策略控制子系统组件的行为.通常三种子系统策略:

  a. 确定一个新提交应用的home-sub-cluster的Router,并且在子集群上为该用户预留特定的资源.

  b. 通过AMRMProxy确定一个子集群的RM,以此来重定向一个AM的资源请求.

  c. 通过YARN RM 在每个子集群上预留资源.

  接下来,我们从高级层面上讨论一下策略的问题.

  3.4.1 Policy Store APIs

  a. getPolicyForAccount (): router/AMRMProxy/RM使用此API来检索要使用的各种参数.

  b. getAllPolicies ():The router/AMRMProxy/RM 使用此API来获取所有策略信息

  c. updatePolicies(): GPG使用此API来更新策略.

  3.5 跨子集群分配资源

  下面开始介绍通过YARN已经存在的"reservation"API来保证跨集群资源分配和负载平衡.

  3.5.1 场景

  我们如何实现跨集群分配资源呢?例如,一个用户请求100个<2 cores, 4GB>的containers,我们如何处理这个请求,根据什么来决定是否接受这个请求?我们从哪里找到主机来满足该资源需求?如果失败了怎么办?这里我们引入reservation的概念,提出一个处理该类请求的框架,然后简要地探讨一下将租户和子集群映射所用到的策略.

  3.5.2 Reservation APIs

   在时机成熟的时候,我们打算在YARN 2.6版本中开发完成预留资源的API,并作为ApplicationClientProtocol的一部分.我们会先开发出一些简单的,缺乏灵活性的部分机制,但是会保证框架支持平滑升级成完全的机制.初始机制不具有任何灵活性.例如,用户必须指定确切的并行container数目,资源和使用这些资源的时间都要指定.就像普通的yarn队列一样,预留的资源可以被多个作业共享,也可以作为一个作业获取资源多种方式中的一种.因为YARN支持多个作业间的动态资源分配,一个作业可以通过申请预留资源保证运行的稳定性.下一步就是支持用户加入时间范围参数来预留资源.已有的YARN预留系统已经具备这个功能了,并且可以与联邦系统兼容.接下来讨论一下完整的预留机制是什么样的.

       3.5.3 预留机制中的容错机制

  为了让联邦系统能够使用预留资源机制,我们必须解决子集群和预留资源之间的映射问题.如下图:预留资源机制设计如下:

  1) 用户通过预留资源API(标准的YARN ApplicationSubmissionProtocol.submitReservation())发送请求给Router.

  2) Router访问Policy Store并获得当前子集群调度计划的拷贝.为了支持部分预留机制,调度计划不会随着时间变化,并且用少量整数就可以描述.
  3) Router会运行一个AdmissionPolicy,它决定一个预留资源请求是否可以被满足,何时满足.

  4) Router会运行PlacementPolicy,它负责将预留资源和该资源所在的子集群映射起来.

  5) Router会把之前的操作持久化到Policy Store中,包括预留资源是否满足,预留资源所在子集群,更新RM调度计划.

  6) 当预留资源成功时,Router会向用户返回一个ReservationID,用户可以在提交作业时使用这个ReservationID来获取预留资源.

  7) RMs会向Router汇报心跳,同时从中获得相应的预留资源策略并保存到本地.

  访问具有事务性,所以允许多个Router同时接受预留资源的请求同时作出调度计划.GPG可以带外执行,并根据集群状况(如集群资源利用率或其它更复杂算法)修改这些计划.这种设计具有很好的容错性.GPG是带外执行的,所以基本操作是不要求GPG存在的.每个Router都可以失败,只要存在一个可用的Router,就可以接受预留资源的请求.StateStore和PolicyStore有可能在某段时间内无法访问,但是因为RMs在本地下载了一份调度计划的拷贝,所以仍然可以继续调度.当Policy Store不可用时,系统是无法接收新的预留资源请求的.

    3.5.4 当前设计局限性

   当前基于预留资源机制的方法利用了YARN已有的算法,所以在将来可以更加容易扩展.但是当前的局限性是YARN不支持层级预留资源机制.扩展当前YARN资源预留机制,使它支持层级预留是非常有用的.但是当前尚不清楚这样做的难度,特别是跨子集群的层级概念.这种概念是独立于当前的设计机制的(队列或者预留资源机制).

 

posted @ 2018-01-10 22:05  哲明1036  阅读(617)  评论(0编辑  收藏  举报