(1) YARN
下一代MapReduce框架的名称,为了容易记忆,一般称为MRv2(MapReduce version 2)。该框架已经不再是一个传统的MapReduce框架,甚至与MapReduce无关,她是一个通用的运行时框架,用户可以编写自己的计算框架,在该运行环境中运行。用于自己编写的框架作为客户端的一个lib,在运用提交作业时打包即可。该框架为提供了以下几个组件:
<1> 资源管理:包括应用程序管理和机器资源管理
<2> 资源双层调度
<3> 容错性:各个组件均有考虑容错性
<4> 扩展性:可扩展到上万个节点
2) ResourceManager
简称“RM”。
MRv2最基本的设计思想是将JobTracker的两个主要功能,即资源管理和作业调度/监控分成两个独立的进程。在该解决方案中包含两个组件:全局的ResourceManager(RM)和与每个应用相关的ApplicationMaster(AM)。这里的“应用”指一个单独的MapReduce作业或者DAG作业。RM和与NodeManager(NM,每个节点一个)共同组成整个数据计算框架。RM是系统中将资源分配给各个应用的最终决策者。AM实际上是一个具体的框架库,它的任务是【与RM协商获取应用所需资源】和【与NM合作,以完成执行和监控task的任务】。
RM有两个组件组成:
调度器(Scheduler)
应用管理器(ApplicationsManager,ASM)
调度器根据容量,队列等限制条件(如每个队列分配一定的资源,最多执行一定数量的作业等),将系统中的资源分配给各个正在运行的应用。这里的调度器是一个“纯调度器”,因为它不再负责监控或者跟踪应用的执行状态等,此外,他也不负责重新启动因应用执行失败或者硬件故障而产生的失败任务。调度器仅根据各个应用的资源需求进行调度,这是通过抽象概念“资源容器”完成的,资源容器(Resource Container)将内存,CPU,磁盘,网络等资源封装在一起,从而限定每个任务使用的资源量。
调度器内嵌有策略可插拔的插件,主要负责将集群中得资源分配给多个队列和应用。当前MapReduce的调度器,如Capacity Scheduler和Fair Scheduler,均可作为该插件。
(3)NodeManager
简称“NM”。
NM是每个节点上的框架代理,主要负责启动应用所需的容器,监控资源(内存,CPU,磁盘,网络等)的使用情况并将之汇报给调度器。
一句话:“NM主要用于管理某个节点上的task和资源”。
(4)ApplicationsManager
简称“ASM”。
ASM主要负责接收作业,协商获取第一个容器用于执行AM和提供重启失败AM container的服务。
一句话:“ASM主要用于管理AM”。
(5)ApplicationMaster
简称“AM”。
AM主要负责同调度器协商以获取合适的容器,并跟踪这些容器的状态和监控其进度。
一句话:“AM主要用于管理其对应的应用程序,如MapReduce作业,DAG作业等”。
(6) Container
容器中封装了机器资源,如内存,CPU, 磁盘,网络等,每个任务会被分配一个容器,该任务只能在该容器中执行,并使用该容器封装的资源。
怎样将某个计算框架(MapReduce,HAMA,Giraph)部署到YARN中?
答:需要编写一个ApplicaionMaster。
MRv2最基本的设计思想是将JobTracker的两个主要功能,即资源管理和作业调度/监控分成两个独立的进程。在该解决方案中包含两个组件:全局的ResourceManager(RM)和与每个应用相关的ApplicationMaster(AM)。这里的“应用”指一个单独的MapReduce作业或者DAG作业。RM和与NodeManager(NM,每个节点一个)共同组成整个数据计算框架。RM是系统中将资源分配给各个应用的最终决策者。AM实际上是一个具体的框架库,它的任务是【与RM协商获取应用所需资源】和【与NM合作,以完成执行和监控task的任务】。
RM有两个组件组成:
调度器(Scheduler)
应用管理器(ApplicationsManager,ASM)
调度器根据容量,队列等限制条件(如每个队列分配一定的资源,最多执行一定数量的作业等),将系统中的资源分配给各个正在运行的应用。这里的调度器是一个“纯调度器”,因为它不再负责监控或者跟踪应用的执行状态等,此外,他也不负责重新启动因应用执行失败或者硬件故障而产生的失败任务。调度器仅根据各个应用的资源需求进行调度,这是通过抽象概念“资源容器”完成的,资源容器(Resource Container)将内存,CPU,磁盘,网络等资源封装在一起,从而限定每个任务使用的资源量。(注:Hadoop-0.23.0【资料一, 资料二】中的Container采用了“监控linux进程”来限制每个任务的资源,即:有个监控线程周期性地从linux虚拟文件系统/proc/中读取相应进程树使用的资源总量,一旦检测到超出限制,则直接kill该task,今后的版本想严格限制内存,CPU,网络,磁盘等资源。
调度器是可插拔的组件,主要负责将集群中得资源分配给多个队列和应用。YARN自带了多个资源调度器,如Capacity Scheduler和Fair Scheduler等。
ASM主要负责接收作业,协商获取第一个容器用于执行AM和提供重启失败AM container的服务。
NM是每个节点上的框架代理,主要负责启动应用所需的容器,监控资源(内存,CPU,磁盘,网络等)的使用情况并将之汇报给调度器。
AM主要负责同调度器协商以获取合适的容器,并跟踪这些容器的状态和监控其进度。
【Resource Manager】资源模型在YARN 1.0中,调度器仅考虑了内存资源。 每个节点由多个固定内存大小(512MB或者1GB)的容器组成。AM可以申请该内存整数倍大小的容器。YARN最终会提供一个更加通用的资源模型,但在Yarn V1中,仅提供了一个相当直接的模型:“资源模型完全是基于内存的,且每个节点由若干个离散的内存块(chunk of memory)组成”。与Hadoop MapReduce不同,MRv2并没有人为的将集群资源分成map slot和reduce slot。MRv2中的每个内存块是可互换的,这就提高了集群利用率—当前Hadoop MapReduce的一个最大问题是由于缺乏资源互换,作业会在reduce slot上存在瓶颈。(“互换”的意思是资源是对等的,所有资源形成一个资源池,任务可以从资源池中申请任意的资源,这就提高了资源利用率)对上一端进一步解释:在当前Hadoop MapReduce中,集群资源会被切分成map slot和reduce slot。在每个TaskTracker上,管理员可配置若干个map slot和reduce slot,slot可看做是令牌,map task拿到一个map slot后才可以运行(对于reduce task类似)。而管理员一般只根据CPU个数配置slot个数时,如果CPU个数为12,则可配置8个map slot,4个reduce slot。这会导致两个问题:(1)实际的计算资源不仅仅是CPU,还有内存,磁盘和网络等,这些均需要考虑,只考虑某一种资源势必会造成机器拥塞,这在共享集群环境下表现尤为显著;(2)MapReduce计算流程是两阶段的,而这两个阶段存在依赖性:reduce task不会进入sort和reduce阶段,直到全部map task计算完成,而实际计算时,map task完成一定的比例,便会启动reduce task,此时启动的reduce task全部处于shuffle阶段,经常会走走停停,导致该map slot资源利用率非常低。在Yarn中,任何一个应用可申请任何内存大小合理(合理是指内存大小必须是memory chunck的整数倍)的容器,也可以申请各种类型的容器。资源协商每个AM使用资源描述来申请一系列容器,其中可能包括一些特殊需求的机器。它也可以申请同一个机器上的多个容器。所有的资源请求是受应用程序容量,队列容量等限制的。AM负责计算应用程序所需的资源量,比如MapReduce的input-splits,并把他们转化成调度器可以理解的协议。当前调度器可理解的协议是。以MapReduce为例,MapReduce AM分析input-splis,并将之转化成以host为key的转置表发送给RM。下图为一个典型的AM资源请求:调度器会尽量匹配该表中的资源;如果某个特定机器上的资源是不可用的,调度器会提供同一个机架或者不同机架上的等量资源代替之。有些情况下,由于整个集群非常忙碌,AM获取的资源可能不是最合适的,此时它可以拒绝这些资源并请求重新分配。调度调度器收集所有正在运行的应用程序的资源请求并构建一个全局规划进行资源分配。调度器会根据应用程序相关的约束(如合适的机器)和全局约束(如队列资源总量,用户可提交作业总数等)分配资源。调度器使用与容量调度类似的概念,采用容量保证作为基本的策略在多个应用程序间分配资源。调度器的调度策略如下:选择系统中“服务最低”的队列(如何定义服务最低?可以是资源利用量最低的队列,即:已使用的资源与总共可用资源比值最小)从该队列中选择优先级最高的作业尽量满足该作业的资源请求调度器APIYarn 调度器与AM之间仅有一个API:Response allocate (Listask, Listrelease)
AM使用一个ResourceRequest列表请求特定资源,并同时可要求释放一些调度器已经分配的容器。
Response包含三方面内容:新分配的容器列表,自从上次AM与RM交互以来已经计算完成的容器的状态(包含该容器中运行task的详细信息),当前集群中剩余资源量。 AM收集完成容器的信息并对失败的任务作出反应。资源剩余量可用于AM调整接下来的资源请求,如MapReduce AM可使用该信息以合理调度maps和reduces从而防止产生死锁。(何以“死锁”?在MapReduce框架中,如果将所有资源分配给了map task,则可能会造成reduce task饥饿,需要合理调整map资源和reduce 资源的比例)
资源监控
调度器周期性地收到NM所在节点的资源变化信息,同时,调度器会将已使用完的容器分配重新分给合适的AM。
AM的生命周期
ASM负责管理系统中所有应用程序的AM,正如上一节所述,ASM负责启动AM,监控AM的运行状态,在AM失败时对其进行重启等。
为了完成该功能,ASM主要有以下几个组件:
(1) SchedulerNegotiator:与调度器协商容器资源,并返回给AM
(2)AMContainerManager:告知NM,启动或者停止某个AM的容器
(3) AMMonitor:查看AM是否活着,并在必要的时候重启AM
【NodeManager】
每个节点上装有一个NM,主要的职责有:
(1)为应用程序启动容器,同时确保申请的容器使用的资源不会超过节点上的总资源。
(2)为task构建容器环境,包括二进制可执行文件,jars等
(3)为所在的节点提供了一个管理本地存储资源的简单服务,应用程序可以继续使用本地存储资源即使他没有从RM那申请。比如:MapReduce可以使用该服务程序存储map task的中间输出结果。
【ApplicationMaster】
每个应用程序均会有一个AM,主要职责有:
(1) 与调度器协商资源
(2) 与NM合作,在合适的容器中运行对应的task,并监控这些task执行
(3) 如果container出现故障,AM会重新向调度器申请资源
(4) 计算应用程序所需的资源量,并转化成调度器可识别的格式(协议)
(5) AM出现故障后,ASM会重启它,而由AM自己从之前保存的应用程序执行状态中恢复应用程序。
注:在MapReduce中,由于AM会定时的保存job的运行时状态,因此,当AM重启时可以恢复对应的job,按照粒度有三种策略:
<1>整个作业重新计算
<2> 保存已经完成的map task和reduce task,只重新计算未完成的task
YARN的资源管理器实际上是一个事件处理器,它需要处理来自外部的6种SchedulerEvent类型的事件,并根据事件的具体含义进行相应的处理。这6种事件含义如下:
(1) NODE_REMOVED
事件NODE_REMOVED表示集群中被移除一个计算节点(可能是节点故障或者管理员主动移除),资源调度器收到该事件时需要从可分配资源总量中移除相应的资源量。
(2) NODE_ADDED
事件NODE_ADDED表示集群中增加了一个计算节点,资源调度器收到该事件时需要将新增的资源量添加到可分配资源总量中。
(3)APPLICATION_ADDED
事件APPLICATION_ADDED 表示ResourceManager收到一个新的Application。通常而言,资源管理器需要为每个application维护一个独立的数据结构,以便于统一管理和资源分配。资源管理器需将该Application添加到相应的数据结构中。
(4)APPLICATION_REMOVED
事件APPLICATION_REMOVED表示一个Application运行结束(可能成功或者失败),资源管理器需将该Application从相应的数据结构中清除。
(5) CONTAINER_EXPIRED
当资源调度器将一个container分配给某个ApplicationMaster后,如果该ApplicationMaster在一定时间间隔内没有使用该container,则资源调度器会对该container进行再分配。
(6)NODE_UPDATE
NodeManager通过心跳机制向ResourceManager汇报各个container运行情况,会触发一个NODE_UDDATE事件,由于此时可能有新的container得到释放,因此该事件会触发资源分配,也就是说,该事件是6个事件中最重要的事件,它会触发资源调度器最核心的资源分配机制。
YARN对内存资源和CPU资源采用了不同的资源隔离方案。对于内存资源,为了能够更灵活的控制内存使用量,YARN采用了进程监控的方案控制内存使用,即每个NodeManager会启动一个额外监控线程监控每个container内存资源使用量,一旦发现它超过约定的资源量,则会将其杀死。采用这种机制的另一个原因是Java中创建子进程采用了fork()+exec()的方案,子进程启动瞬间,它使用的内存量与父进程一致,从外面看来,一个进程使用内存量可能瞬间翻倍,然后又降下来,采用线程监控的方法可防止这种情况下导致swap操作。对于CPU资源,则采用了Cgroups进行资源隔离。
资源分配模型
在YARN中,用户以队列的形式组织,每个用户可属于一个或多个队列,且只能向这些队列中提交application。每个队列被划分了一定比例的资源。
YARN的资源分配过程是异步的,也就是说,资源调度器将资源分配给一个application后,不会立刻push给对应的ApplicaitonMaster,而是暂时放到一个缓冲区中,等待ApplicationMaster通过周期性的RPC函数主动来取,也就是说,采用了pull-based模型,而不是push-based模型,这个与MRv1是一致的。
总结
相比于MRv1中的资源调度器,尽管YANR的调度器也是插拔式的,但由于YARN采用了事件驱动的模型,因此编写起来更加复杂,难度也远远大于MRv1。
同MRv1一样,YARN也自带了三种常用的调度器,分别是FIFO,Capacity Scheduler和Fair Scheduler,其中,第一个是默认的调度器,它属于批处理调度器,而后两个属于多租户调度器,它采用树形多队列的形式组织资源,更适合公司应用场景。