1. Yarn简介
1.1. Yarn的由来
对于业界的大数据存储及分布式处理系统来说,hadoop是耳熟能详的卓越开源分布式存储及处理框架,在hadoop原MapReduce架构如下:
从上图我们可以清楚的看出原MapReduce程序的流程以及设计思路:
- 首先用户程序(JobClinet)提交一个job,job的信息会发送到jobTracker中,JobTracker是Map-Reduce框架的中心,他需要与集群中的机器定时通讯(hearbeat),需要管理那些程序应该跑在那些机器上,需要管理所有job失败、重启等操作。
- TaskTracker是Map-Reduce集群中每台机器都有的一个部分,他做的事情主要是监视自己所在机器的资源情况。
- TaskTracker同时监控当前机器的tasks运行情况。TaskTracker需要把这些信息通过hearbeat发送给JobTracker,JobTracker会搜集这些信息已给新提交的job分配运行在那些机器上。
可以看出原来的MapReduce架构是简单明了的,在最初推出的几年,也得到了众多的成功案例,或的业界广泛的支持和肯定,但是随着分布式系统集群的规模和其他工作负荷的增长,原框架的问题逐渐浮出水面,主要的问题集中如下:
- JobTracker是Map-Reduce的集中处理点,存在单点故障。
- JobTracker完成了太多的任务(资源调度、任务分配跟踪、异常处理),造成了过多的额资源消耗,当Map-Reduce job非常多的时候,会造成很大的内存开销,潜在来说,也增加了jobTracker fail的风险,这也是业界普遍总结出老hadoop的Map-Reduce只能支持4000节点主机的上限。
- 在taskTracker端,以Map/reduce task的数据作为资源的表示过于简单,没有考虑到CPU/MEM的占用情况,如果两个大内存消耗的task被调度到了一块,很容易出现OOM。
- 在TaskTracker端,把资源强制划分为map task slot和reduce task slot,如果当系统中只有map task或者只有reduce task的时候,会变成资源的浪费,也就是前面提过的集群资源利用的问题。
- 源代码层面分析的时候,会发现代码非常的困难,常常因为一个class做了太多的事情,代码量达到3000多行,造成class的任务不清晰,增加bug修复和版本维护的难度。
- 从操作的角度来看,现在的hadoop MapReduce框架在有任何重要的或者不重要的变化(例如bug修复,性能提升和特性化)时,都会强制进行系统级别的升级更新。更糟糕的是,他不管用户的喜好,强制让分布式集群系统的每个用户端同时更新。这些更新会让用户为了验证他们之前的应用程序是不是适合新的hadoop版本而浪费大量时间。
1.2. Yarn框架原理及运作机制
从业界使用分布式系统的变化趋势和hadoop框架的长远发展来看,MapReduce的jobTracker/TaskTracker机制需要大规模的调整来修复它在扩展性,内存消耗,线程模型,可靠性和性能上的缺陷。在过去的几年中,hadoop开发团队做了一些bug的修复,但是最近这些修复的成本越来越高,这表明对原框架作出改变的难度越来越大。
为从根本上解决旧MapReduce框架的性能瓶颈,促进Hadoop框架的更长远发展,从0.23.0版本开始,Hadoop的MapReduce框架完全重构,发生了根本的变化。新的Hadoop MapReduce框架命名为MapReduce V2或者叫Yarn,其框架如下图所示:
重构根本的思想是将JobTracker两个主要的功能分离成单独的组件,这两个功能是资源管理和任务调度/监控。新的资源管理器全局管理所有应用程序计算资源的分配,每一个应用的ApplicationMaster负责相应的调度和协调。一个应用程序无非是一个单独的传统的MapReduce任务或者是一个DAG(有向无环图)任务。ResourceManager和每一台机器的节点管理服务器都能够管理用户在那台机器上的进程并对计算进行组织。
事实上,每一个应用的ApplicationMaster是一个详细的框架库,它结合从ResourceManager获得的资源和NodeManager协同工作来运行和监控任务。
上图中ResourceManager支持分层级的应用队列,这些队列分享有集群一定比例的资源。从某种意义上讲他就是一个纯粹的调度器,他在执行过程中不对应用进行监控和状态跟踪。同样,他也不能重启因应用失败或者硬件错误而运行失败的任务。
ResourceManager是基于应用程序对资源的需求进行调度的;每一个应用程序需要不同类型的资源,因此就需要不同的容器。资源包括:MEM、CPU、disk、网络等等。可以看出,这同现MapReduce固定类型的资源使用模型有显著的却别,他给集群的使用带来负面的影响。资源管理器提供一个调度策略的插件,他负责将集群资源分配给多个队列和应用程序。调度插件key8i基于现有的能力调度和公平调度模型。
上图中NodeManager是每一台机器框架的代理,是执行应用程序的容器,监控应用程序的资源使用情况(CPU、MEM、DISK、网络)并向调度器汇报。
每一个应用的ApplicationMaster的职责有:向调度器索要适当的资源容器,运行任务,跟踪应用程序的状态和监控他们的进程,处理任务的失败原因。
1.3. 新旧Hadoop MapReduce框架对比
让我们来对新旧MapReduce框架做详细的分析和对比,可以看到有以下几个显著变化:
首先客户端不变,其调用API及接口大部分保持兼容,这也是为了对开发者透明化,使其不必对原有代码做大的改变,但是原框架中核心的JobTracker和TaskTracker不见了,取而代之的是ResourceManager、ApplicationMaster与NodeManager三部分。
我们来详细解释这三部分,首先ResourceManager是一个中心的服务,它做的事情是调度、启动每一个Job所属的ApplicationMaster、另外监控ApplicationMaster的存在情况。Job里面所在的task的监控、启动等等内容不见了。这就是AppMst存在的原因。ResourceManager负责作业与资源的调度。接收JobSubmitter提交的作业,按照作业的上下文信息,以及从NodeManager收集来的状态信息,启动调度过程,分配一个Container作为App Mstr。
NodeManager功能比较专一,就是负责Container状态的维护,并向RM保持心跳。
ApplicationMaster负责一个Job生命周期内的所有工作,类似老的框架中jobTracker。但注意每一个Job都有一个ApplicationMaster,他可以运行在ResourceManager以外的机器上。
Yarn框架相对于老的MapReduce框架生命优势呢?我们可以看到:
- 这个设计大大减少了JobTracker的资源消耗,并且让检测每一个Job子任务状态的程序分布式化了,更安全、更优美。
- 在新的Yarn中,ApplicationMaster是一个可变的部分,用户可以对不同的变成模型写自己的AppMst,让更多类型的编程模型能够跑在Hadoop集群中,可以参考Hadoop Yarn官方配置模板中的mapred-site.xml配置。
- 对于资源的表示以内存为单位(在目前版本的yarn中,没有考虑cpu的占用),比之前所剩余slot数据更合理。
- 老的框架中,jobTracker一个很大的负担就是监控job下的tasks的运行状况,现在这个部分就扔给applicationMaster做了,而ResourceManager中有一个模板叫做ApplicationsMasters(注意不是ApplicationMaster),它是检测ApplicationMaster的运行状况,如果出问题,会将其在其他机器上启动。
- Container是yarn为了将来作资源隔离而提出的一个框架。这一点应该借鉴了mesos的工作,目前是一个框架,仅仅提供java虚拟机内存的隔离,Hadoop团队的设计思路应该后续能支持更多的资源调度和控制,既然资源表示成内存量,那就没有了之前的map slot/reduce slot分开造成集群资源闲置的尴尬情况。
2. Yarn组成详解
2.1. ResourceManager(RM)
RM是一个全局的资源管理器,负责整个系统的资源管理和分配。它主要有两个组件构成:调度器(Scheduler)和应用程序管理器(Applications Manager,ASM)。
1、 调度器(Scheduler)
调度器根据容量、队列等限制条件(如每个队列分配一定的资源,最多执行一定数量的作业等),将系统中的资源分配给各个正在运行的应用程序。需要注意的是,该调度器是一个“纯调度器”,它不再从事任何与具体应用程序相关的工作,比如不负责监控或者跟踪应用的执行状态等,也不负责重新启动因应用执行失败或者硬件故障而产生的失败任务,这些均交由应用程序相关的ApplicationMaster完成。调度器仅根据各个应用程序的资源需求进行资源分配,而资源分配单位用一个抽象概念“资源容器”(Resource Container,简称Container)表示,Container是一个动态资源分配单位,它将内存、cpu、磁盘、网络等资源封装在一起,从而限定每个任务使用的资源量。此外,该调度器是一个可插拔的组件,用户可根据自己的需求设计新的资源量。此外,调度器是一个可插拔的组件,用户可以根据自己的需要设计新的调度器,yarn提供了多种直接可用的调度器,比如Fair Scheduler和Capacity Scheduler等。
2、应用程序管理器(Applications Manager)
应用程序管理器负责管理整个系统中所有应用程序,包括应用程序提交、与调度器协商资源已启动ApplicationMaster、监控ApplicationMaster运行状态并在失败时重新启动它等。
2.2. ApplicationMaster(AM)
用户提交的每个应用程序均包含一个AM,主要功能包括:
- 与RM调度器协商以获取资源(用Container表示);
- 将得到的任务进一步分配给内部的任务;
- 与NM通讯以启动/停止任务;
- 监控所有任务运行状态,并在任务运行失败的时候重新为任务申请资源以重启任务。
当前yarn自带了两个AM实现,一个用户演示AM编写方法的实例程序distributedshell,他可以申请一定数目的container以并运行一个shell命令或者shell脚本;另一个是运行MapReduce应用程序的AM—MRAppMaster。此外,一些其他的计算框架对应的AM正在开发中,比如open MPI、Spark等。
2.3. NodeManager(NM)
NM是每个节点上的资源和任务管理器,一方面,它会定时的向RM汇报本节点上的资源使用情况和各个container的运行状态;另一个方面,他接受并处理来自AM的container启动/停止各种请求。
2.4. Container
Container是yarn中的资源抽象,他封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等,当AM向RM申请资源时,RM为AM返回的资源便是Container表示的。Yarn会为每个任务分配一个Container,且该任务只能使用该Container中描述的资源。需要注意的是,Container不同与MRv1中的slot,他是一个动态资源划分单位,是根据应用程序的需求动态生成的。到目前为止,yarn仅支持CPU和内存两种资源,且使用了轻量级资源隔离机制Cgroups进行资源隔离。
3. Yarn运行流程
1、 MR JobClient向resourceManager(AsM)提交一个job;
2、 AsM向Scheduler请求一个供MR AM运行的container,然后启动它
3、MR AM启动起来后向AsM注册
4、MR JobClient向AsM获取到MR AM相关的信息,然后直接与MR AM进行通讯
5、MR AM计算splits并未所有的map构造资源请求
6、MR AM做一些必要的MR OutPutCommiter的准备工作
7、MR AM向RM(Scheduler)发起资源请求,得到一组供MAP/Reduce task运行的container,然后与NM一起对每一个container执行一些必要的任务,包括资源本地化等。
8、MR AM监视运行着的task知道完成,当task失败时,申请新的container运行失败的task
9、当每一个map/reduce task完成后,MR AM运行MR OutPutCommiter的clean up代码,也就是进行一些收尾工作。
10、当所有的map/reduce完成后,MR AM运行OutPutCommitter的必要的job commit或者abort APIs.
11、MR AM退出。
4. Yarn对资源的调度和隔离
Yarn同时支持MEM和CPU两种资源的调度(默认仅支持内存,如果想进一步调度CPU需要自己进行一些配置)。在yarn中,资源管理由ResourceManager和nodeManager共同完成,其中ResourceManager中的调度器负责资源的分配,而NodeManager负责资源的供给和隔离。ResourceManager将某个NodeManager上资源分配给任务(这就是所谓的“资源调度”)后,NodeManager需按照要求为任务提供相应的资源,甚至保证这些资源应具有独占性,为任务运行提供基础的保证,这就是资源隔离。
在正式介绍具体的资源调度和隔离之前,先品味一下内存和CPU这两种资源的特殊点,这是两种性质不同的资源。内存资源的多少会决定任务的生死,如果内存不够,任务可能会运行失败;相比之下,CPU资源则不同,他只会决定任务运行的快慢,不会对生死产生影响。
4.1. Yarn对内存资源的调度和隔离
基于以上考虑,yarn允许用户配置 节点上可用的物理内存资源,注意,这里是“可用的”,因为一个节点上的内存会被若干个服务共享,比如一部分给yarn,一部分给HDFS,一部分给hbase等,yarn配置的只是自己可以使用的,配置参数如下:
1、 yarn.nodemanager.resource.memory-mb
表示该节点上yarn可使用的物理内存总量,默认是8G,注意如果你的节点内存不够8G,则需要调小这个值,而yarn不能只能的探测节点的物理内存总量;
2、 yarn.nodemanager.resource.vmem-pmem-ratio
任务每使用1MB物理内存,最多可使用虚拟内存量,默认是2.1
3、yarn.nodemanager.pmem-check-enabled
是否启动一个线程检查么个任务正在使用的物理内存量,如果任务超出分配值,则直接将其杀死,默认为true。
4、yarn.nodemanager.vmem-check-enabled
是否启动一个线程检查每个任务正使用的虚拟内存量,如果任务超出分配值,则直接将其杀死,默认为true。
5、 yarn.scheduler.minimum-allocation-mb
单个任务可申请的最小物理内存量,默认是1024M,如果一个任务申请的物理内存量少于该值,则对应的值改为这个数。
6、yarn.scheduler.maximum-allocation-mb
单个任务可申请的最多物理内存量,默认是8G。
默认情况下,yarn采用了线程监控的方法判断任务是否超量使用内存,一旦发现超量,则直接将其杀死。由于Cgroups对内存的判断缺乏灵活性(即任务任何时刻不能超过内存上限,如果超过,则直接将其杀死或者报OOM),而java进程在创建瞬间内存翻倍,之后骤降到正常值,这种情况下,采用线程监控的方式更加灵活(当发现进程树内存瞬间翻倍超过设定值时,可以认为是正常现象,不会将任务杀死),因此yarn未采用Cgroups内存隔离机制。
4.2. Yarn对CPU资源的调度和隔离
在yarn中,CPU资源的额组织方式仍然在探索中,目前只是一个初步的,非常粗粒度的实现方式,更细粒度的CPU划分方式已经提出来了,正在完善和实现中。
目前CPU被划分为虚拟CPU(CPU virtual core),这里的虚拟CPU是yarn自己引入的概念,初衷是,考虑到不同节点的CPU性能可能不同,么个CPU具有的计算能力也不是一样的,比如某个物理CPU的计算能力可能是另外一个物理CPU的2倍,这时候,你可以通过一个物理CPU多配置几个虚拟CPU弥补这种差异。用户提交作业时,可以指定每个任务所需要的CPU个数。在yarn中,CPU相关的配置参数如下:
1、yarn.nodemanager.resource.cpu-vcores
表示该节点上yarn可以使用的虚拟CPU个数,默认是8。注意,目前推荐将该值设置为物理CPU核数相同。如果你的节点CPU核数不够8个,则需要调减小这个值,而yarn不会智能探测节点的物理CPU总数。
2、yarn.scheduler.minimum-allocation-vcores
单个任务可申请的最小虚拟CPU个数,默认是1。如果一个任务申请的CPU个数少于该数值,则该对应的值改为这个数。
3、 yarn.scheduler.maximum-allocation-vcores
单个任务可申请的最多虚拟CPU个数,默认值是32。
默认情况下,yarn是不会对CPU资源进行调度的,需要你配置相应的资源调度器让你支持。默认情况下,NodeManager不会对CPU资源进行任何隔离,你可以通过启动Cgroups让你支持CPU隔离。
由于CPU资源的独特性,目前这种CPU分配方式仍然是粗粒度的。举个例子,很多任务可能是IO秘籍行的,消耗的CPU资源非常少,比如此时你为它分配一个CPU,则是一种严重浪费,你完全可以让它与其他几个任务公用一个CPU,也就是说,我们需要支持更细粒度的CPU表达方式。
5. Hadoop权限管理
5.1. 简介
Hadoop权限管理包括以下几个模块:①用户分组管理。用户按组为单位组织管理,某个用户只能向固定分组中提交作业,只能使用固定分组中配置的资源;同时可以限制每个用户提交的作业数,使用的资源量等;②作业管理。包括作业提交权限控制,作业运行状态查看权限控制等。如:可以限定提交作业的用户;可限定可查看作业运行状态的用户;可限定普通用户只能修改自作业优先级,kill自己的作业;高级用户可以控制所有作业等。
想要支持权限管理需要使用fair scheduler或者capacity scheduler(作业管理需要用到ACL(access control list)功能,启用该功能需要选择一个支持多队列管理的调度器)
5.2. 基本属于
- 用户(user):hadoop使用linux用户管理,hadoop中的用户就是linux中的用户;
- 分组(group):hadoop使用linux分组管理,hadoop中的分组就是linux中的分组;
- 池(pool):hadoop fair scheduler中的概念,一个pool可以是一个user,一个group或者一个queue;
- 队列(queue):队列是hadoop提出的概念,一个queue可以有任意几个group或者几个user组成。
5.3. Fair Scheduler
Facebook开发的适合共享环境的调度器,支持多用户分组管理,么个分组可以配置资源量,也可限制每个用户和每个分组中的并发运行作业数量;每个作业的作业有优先级,优先级越高分配的资源越多。
5.4. Capacity Scheduler
Yahoo开发的适合共享环境的调度器,支持多用户多队列管理,每个队列可以配置资源量,也可限制每个用户和每个队列的并发运行作业数量,也可限制每个作业使用的内存量;每个用户的作业有优先级,在单个队列中,作业按照先来先服务(实际上是先按照优先级,优先级相同的再按照作业提交时间)的原则进行调度。
5.5. Fair Scheduler vs Capacity Scheduler
1、相同点
- 均支持多用户多队列,即:适用于多用户共享集群的使用环境
- 单个队列均支持优先级和FIFO调度方式
- 均支持资源共享,即摸个queue中的资源有剩余时,可以共享给其他缺资源的queue。
2、不同点
- 核心调度策略不同。计算能力调度器的调度策略是,先选择资源利用率低的queue,然后在queue中同事考虑FIFO和memory constraint因素;而公平调度器仅考虑公平,而公平是通过作业缺额体现的,调度器每次选择缺额最大的job。
- 内存约束。计算能力调度器调度job时会考虑作业的内存限制,为了满足某些特殊job的特殊内存需求,可能会为该job分配多个slot;而公平调度器对这种特殊的job无能为力,只能杀掉这种task。
3、功能上的不同
Fair Scheduler不允许配置每个user使用的slot数上限,但允许抢占资源;而capactiy Scheduler允许配置每个user使用的slot数上限,但暂时不支持资源抢占。