目录
一:什么是Yarn
二、Yarn的组件及架构
三、Yarn的组件详解
3.1 Container
3.2 Node Manager
3.3 Resource Manager
3.4 Application Master
四、Yarn request分析
4.1 应用提交过程分析
4.2 Resource Request和Container
五: Yarn各个组件之间的心跳信号(通信)
六: Yarn资源调度算法(调度器)。
集群资源调度器需要解决:
资源调度器需要解决如何合理的分配资源:
Yarn使用队列解决多租户中共享资源问题:
Yarn支持三种资源调度器:
FIFO调度器
Capacity Scheduler容量调度器 (推荐使用)
Fair Scheduler资源调度器
Hadoop 的三种调度器图解FIFO、Capacity Scheduler、Fair Scheduler
在CDH 中开启Capacity Scheduler容量调度器
1.在ResourceManager中配置它要使用的调度器,配置方式是修改conf/yarn-site.xml,设置属性:
2.在Capacity Scheduler专属配置文件capacity-scheduler.xml,需要说明默认存在root的queue,其他的队列都是它的子队列。
Yarn 内存分配管理机制及相关参数配置
一:什么是Yarn
Yarn是Hadoop集群的资源管理系统。Hadoop2.0对MapReduce框架做了彻底的设计重构,我们称Hadoop2.0中的MapReduce为MRv2或者Yarn。在介绍Yarn之前,我们先回头看一下Hadoop1.x对MapReduce job的调度管理方式,它主要包括两部分功能:
1. ResourceManagement 资源管理
2. JobScheduling/JobMonitoring 任务调度监控
到了Hadoop2.x也就是Yarn,它的目标是将这两部分功能分开,也就是分别用两个进程来管理这两个任务:
1. ResourceManger
2. ApplicationMaster
需要注意的是,在Yarn中我们把job的概念换成了application
,因为在新的Hadoop2.x中,运行的应用不只是MapReduce了,还有可能是其它应用如一个DAG(有向无环图Directed Acyclic Graph,例如storm应用)。Yarn的另一个目标就是拓展Hadoop,使得它不仅仅可以支持MapReduce计算,还能很方便的管理诸如Hive、Hbase、Pig、Spark/Shark等应用。这种新的架构设计能够使得各种类型的应用运行在Hadoop上面,并通过Yarn从系统层面进行统一的管理,也就是说,有了Yarn,各种应用就可以互不干扰的运行在同一个Hadoop系统中,共享整个集群资源,如下图所示:
二、Yarn的组件及架构
Yarn主要由以下几个组件组成:
1. ResourceManager:Global(全局)的进程: 集群资源的分配与调度 2. NodeManager:运行在每个节点上的进程: 单节点资源的管理 3. ApplicationMaster:Application-specific(应用级别)的进程 - *Scheduler:是ResourceManager的一个组件* - *Container:节点上一组CPU和内存资源*
Container是Yarn对计算机计算资源的抽象,它其实就是一组CPU和内存资源,所有的应用都会运行在Container中。ApplicationMaster是对运行在Yarn中某个应用的抽象,它其实就是某个类型应用的实例,ApplicationMaster是应用级别的,它的主要功能就是向ResourceManager(全局的)申请计算资源(Containers)并且和NodeManager交互来执行和监控具体的task。Scheduler是ResourceManager专门进行资源管理的一个组件,负责分配NodeManager上的Container资源,NodeManager也会不断发送自己Container使用情况给ResourceManager。
ResourceManager和NodeManager两个进程主要负责系统管理方面的任务。ResourceManager有一个Scheduler,负责各个集群中应用的资源分配。对于每种类型的每个应用,都会对应一个ApplicationMaster实例,ApplicationMaster通过和ResourceManager沟通获得Container资源来运行具体的job,并跟踪这个job的运行状态、监控运行进度。
下面我们看一下整个Yarn的架构图:
三、Yarn的组件详解
3.1 Container
Container是Yarn框架的计算单元,是具体执行应用task(如map task、reduce task)的基本单位。Container和集群节点的关系是:一个节点会运行多个Container,但一个Container不会跨节点。
一个Container就是一组分配的系统资源,现阶段只包含两种系统资源 也就是CPU和Memory(之后可能会增加磁盘、网络等资源),
既然一个Container指的是具体节点上的计算资源,这就意味着Container中必定含有计算资源的位置信息:计算资源位于哪个机架的哪台机器上。所以我们在请求某个Container时,其实是向某台机器发起的请求,请求的是这台机器上的CPU和内存资源。
任何一个job或application必须运行在一个或多个Container中,在Yarn框架中,ResourceManager只负责告诉ApplicationMaster哪些Containers可以用,ApplicationMaster还需要去找NodeManager请求分配具体的Container。
3.2 Node Manager
NodeManager进程运行在集群中的节点上,每个节点都会有自己的NodeManager。NodeManager是一个slave服务:它负责接收ResourceManager的资源分配请求,分配具体的Container给应用。同时,它还负责监控并报告Container使用信息给ResourceManager。通过和ResourceManager配合,NodeManager负责整个Hadoop集群中的资源分配工作。ResourceManager是一个全局的进程,而NodeManager只是每个节点上的进程,管理这个节点上的资源分配和监控运行节点的健康状态。下面是NodeManager的具体任务列表:
1.接收ResourceManager的请求,分配Container给应用的某个任务
2. 和ResourceManager交换信息以确保整个集群平稳运行。ResourceManager就是通过收集每个NodeManager的报告信息来追踪 整个集群健康状态的,而NodeManager负责监控自身的健康状态。
3.管理每个Container的生命周期
4.管理每个节点上的日志
5.执行Yarn上面应用的一些额外的服务,比如MapReduce的shuffle过程
当一个节点启动时,它会向ResourceManager进行注册并告知ResourceManager自己有多少资源可用。在运行期,通过NodeManager和ResourceManager协同工作,这些信息会不断被更新并保障整个集群发挥出最佳状态。
NodeManager只负责管理自身的Container,它并不知道运行在它上面应用的信息。负责管理应用信息的组件是ApplicationMaster,在后面会讲到。
3.3 Resource Manager
ResourceManager主要有两个组件:Scheduler和ApplicationManager。
Scheduler是一个资源调度器,它主要负责协调集群中各个应用的资源分配,保障整个集群的运行效率。Scheduler的角色是一个纯调度器,它只负责调度Containers,不会关心应用程序监控及其运行状态等信息。同样,它也不能重启因应用失败或者硬件错误而运行失败的任务
Scheduler是一个可插拔的插件,它可以调度集群中的各种队列、应用等。在Hadoop的MapReduce框架中主要有两种Scheduler:Capacity Scheduler和Fair Scheduler,关于这两个调度器后面会详细介绍。
另一个组件ApplicationManager主要负责接收job的提交请求,为应用分配第一个Container来运行ApplicationMaster,还有就是负责监控ApplicationMaster,在遇到失败时重启ApplicationMaster运行的Container。
3.4 Application Master
ApplicationMaster的主要作用是向ResourceManager申请资源并和NodeManager协同工作来运行应用的各个任务然后跟踪它们状态及监控各个任务的执行,遇到失败的任务还负责重启它。
在MR1中,JobTracker即负责job的监控,又负责系统资源的分配。而在MR2中,资源的调度分配由ResourceManager专门进行管理,而每个job或应用的管理、监控交由相应的分布在集群中的ApplicationMaster,如果某个ApplicationMaster失败,ResourceManager还可以重启它,这大大提高了集群的拓展性。
在MR1中,Hadoop架构只支持MapReduce类型的job,所以它不是一个通用的框架,因为Hadoop的JobTracker和TaskTracker组件都是专门针对MapReduce开发的,它们之间是深度耦合的。Yarn的出现解决了这个问题,关于Job或应用的管理都是由ApplicationMaster进程负责的,Yarn允许我们自己开发ApplicationMaster,我们可以为自己的应用开发自己的ApplicationMaster。这样每一个类型的应用都会对应一个ApplicationMaster,一个ApplicationMaster其实就是一个类库。这里要区分ApplicationMaster*类库和ApplicationMaster实例*,一个ApplicationMaster类库何以对应多个实例,就行java语言中的类和类的实例关系一样。总结来说就是,每种类型的应用都会对应着一个ApplicationMaster,每个类型的应用都可以启动多个ApplicationMaster实例。所以,在yarn中,是每个job都会对应一个ApplicationMaster而不是每类。
Yarn 框架相对于老的 MapReduce 框架什么优势呢?
1.这个设计大大减小了 ResourceManager 的资源消耗,并且让监测每一个 Job 子任务 (tasks) 状态的程序分布式化了,更安全、更优美。
2.在新的 Yarn 中,ApplicationMaster 是一个可变更的部分,用户可以对不同的编程模型写自己的 AppMst,让更多类型的编程模型能够跑在 Hadoop 集群中,可以参考 hadoop Yarn 官方配置模板中的 ``mapred-site.xml`` 配置。
3.对于资源的表示以内存为单位 ( 在目前版本的 Yarn 中,没有考虑 cpu 的占用 ),比之前以剩余 slot 数目更合理。
4.老的框架中,JobTracker 一个很大的负担就是监控 job 下的 tasks 的运行状况,现在,这个部分就扔给 ApplicationMaster 做了,而 ResourceManager 中有一个模块叫做 ApplicationsManager,它是监测 ApplicationMaster 的运行状况,如果出问题,会将其在其他机器上重启。
5.Container 是 Yarn 为了将来作资源隔离而提出的一个框架。这一点应该借鉴了 Mesos 的工作,目前是一个框架,仅仅提供 java 虚拟机内存的隔离 ,hadoop 团队的设计思路应该后续能支持更多的资源调度和控制 , 既然资源表示成内存量,那就没有了之前的 map slot/reduce slot 分开造成集群资源闲置的尴尬情况。
四、Yarn request分析
4.1 应用提交过程分析
了解了上面介绍的这些概念,我们有必要看一下Application在Yarn中的执行过程,整个执行过程可以总结为三步:
- 应用程序提交
- 启动应用的ApplicationMaster实例
- ApplicationMaster实例管理应用程序的执行
1. 当我们在客户端的某一个节点提交了程序时,也就是客户端程序向ResourceManager提交应用让程序作业连接集群,yarn框架会创建一个yarnrunner,yarnrunner向ResourceManager提交应用并请求一个ApplicationMaster实例
2、RM会返回给客户端application资源的路径,如HDFS://xxxx.../.staging以及application_id
3、yarnrunner提交任务运行所需资源文件。所需资源文件有程序 jar包,job.split,job.xml
4、资源提交完会向RM申请ApplicationMaster。
5、ResourceManager将用户的请求初始化成一个task
6、NodeManager领取到task任务
7、将资源文件下载到本地,并创建容器container.在容器中会启动这个ApplicationMaster。
8、ApplicationMaster向ResourceManager申请map task的容器
9、NodeManager从ResourceManager领取任务创建容器。
10、有了容器之后,ApplicationMaster会将资源文件发送给容器,自此开始执行map task
11、map task执行结束后,ApplicationMaster会向ResourceManager再次申请 reduce task的容器。
4.2 Resource Request和Container
Yarn的设计目标就是允许我们的各种应用以共享、安全、多租户的形式使用整个集群。并且,为了保证集群资源调度和数据访问的高效性,Yarn还必须能够感知整个集群拓扑结构。为了实现这些目标,ResourceManager的调度器Scheduler为应用程序的资源请求定义了一些灵活的协议,通过它就可以对运行在集群中的各个应用做更好的调度,因此,这就诞生了Resource Request和Container。
具体来讲,一个应用先向ApplicationMaster发送一个满足自己需求的资源请求,然后ApplicationMaster把这个资源请求以resource-request
的形式发送给ResourceManager的Scheduler,Scheduler再在这个原始的resource-request
中返回分配到的资源描述Container。每个ResourceRequest可看做一个可序列化Java对象,包含的字段信息如下:
<resource-name, priority, resource-requirement, number-of-containers>
- resource-name:资源名称,现阶段指的是资源所在的host和rack,后期可能还会支持虚拟机或者更复杂的网络结构
- priority:资源的优先级
- resource-requirement:资源的具体需求,现阶段指内存和cpu需求的数量
- number-of-containers:满足需求的Container的集合
number-of-containers
中的Containers就是ResourceManager给ApplicationMaster分配资源的结果。Container就是授权给应用程序可以使用某个节点机器上CPU和内存的数量。
ApplicationMaster在得到这些Containers后,还需要与分配Container所在机器上的NodeManager交互来启动Container并运行相关任务。当然Container的分配是需要认证的,以防止ApplicationMaster自己去请求集群资源。
五: Yarn各个组件之间的心跳信号(通信)
Application Master 与 Resource Manager心跳
AM -> RM
对Container的资源请求,(CPU和Memory)和资源需求的优先级
已用完等待回收的Container列表
RM -> AM
新申请到的Container(也就是说对应的CPU资源和内存资源被分配下来了)
已完成的Container状态
Application Master 与 Node Manager心跳
AM -> AM
发起启动Container请求
NM -> AM
汇报Container状态
Node Manager与Resource Manager心跳
NN -> RM
Node Manager上所有的Container状态
RM -> NM
以删除和等待的Container列表, 那么当NN接收到列表之后他就会去清理对应的Container。
六: Yarn资源调度算法(调度器)。
集群资源调度器需要解决:
多租户(Multi-tenancy): 多用户同时提交多种应用程序,(我们的集群往往是共享给很多用户进行使用,在同一时刻, 会有很多的用户向集群提交各种各样的作业或者应用来运行, 那么这个时候资源调度器,需要来解决如何合理的公平的分配这些资源 而不会使得某个用户下的某个资源饿死)
资源调度器需要解决如何合理的分配资源:
可扩展性(Scalability): 增加集群机器的数量可以快速提高整体的集群性能、这些都是横向扩展而不是纵向的去升级节点上的配置。
Yarn使用队列解决多租户中共享资源问题:
root #根节点
|----prd #
|----dev #开发队列
|--eng #在根据部门的不同去切分不同的队列,给工程人员使用
|---science #给分析人员使用
Yarn支持三种资源调度器:
FIFO
Capacity Scheduler
Fair Scheduler
后两种调度器在生产环境中经常使用,这两种调度器都支持CPU和内存的资源调度
在Hadoop3.0版本后,这两种几乎一样CDH默认使用Fair Scheduler 公平调度器
FIFO调度器
他会像整个集群提交的作业都是用一个队列来进行服务,所以根据提交作业的顺序来进行运行,先来先服务。
优点: 简单易懂,可以按照作业优先级调度
缺点: 他会使得整个集群的利用率不高,并且它并不允许抢占,比如说我们有紧急任务的时候,他是不允许你抢占的。
Capacity Scheduler容量调度器 (推荐使用)
root
|------prd 70%
|------dev 30%
|------eng 50%
|------science 50%
解释: 第一层更具属性不通分为了: 生产任务 和 开发任务, 开发任务又分为了 两个开发部门 使用的队列
我们首先要保证整个集群的资源给 生产部门 使用, 因为可能会有要求说, 生产类型的作业再一定时间之内计算出来, 来保证集群正常的运转,所以说给生产队列预留70%, 而开发类型的作业,预留 30%, 因为开发类型的作业资源不足的话,是可以等待的,而为了划分更加公平,可能会有不通部门的人员来使用, 所以,划分为 eng 和 science 队列各持50%的资源,这样就会保证每隔队列计算资源的能力!
设计思想:
资源是按照比例,来分配给各个队列。
特点:
计算保证能力,以队列为单位划分资源,每个队列资源保证!
灵活性: 当某个队列的资源空闲的时候,他的资源可以分配给其他队列使用。比如说我们再晚上的时候dev开发队列比较空闲,但是晚上有大量的生产任务,那么这个时候Capacity Schedule允许 dev这个队列拿出一部分资源来给这个 prd队列使用,具有一定的灵活性。
支持优先级:
多租户:
综合考虑多种因素防止单个作业、用户或者队列独占资源。
每个队列可以配置一定比例的最低资源配置和使用上限。
每个队列有严格的访问控制,也就是说,当前的用户给他分配到某一个队列当中,那么她只能再当前用户提交作业,不可以像其他的队列递交任务只能想自己的队列,提交任务。
基于资源的调度:
支持内存资源调度和CPU资源调度
支持抢占(2.8.0版本开始)
Fair Scheduler资源调度器
设计思想
资源公平分配
具有与Capacity Scheduler相似的特点,
树状队列
每个队列有独立的最小资源保证
空闲时可以分配资源给其他队列使用
支持内存资源调度和CPU资源调度
支持抢占
不同点
核心调度策略不同
Capacity Scheduler优先选择资源利用率很低的队列
公平调度器考虑的是公平,公平体现在作业对资源的缺额
单独设置队列间资源分配的方式
FAIR
DRF (主资源公平调度) 试图去均衡所有支配性的资源, 打个比方说:
任务A是一个内存式运行的, 任务B他是CUP式运行的, 那么这个DRF会去使得每个任务获取相同比例的支配性资源, 如果我们的当 前系统有9个CPU 和 18 G的内存
那么任务A需要1CPU+4G内存,总共消耗了9分之1的CPU和9分之2内存。 任务B需要3CPU+1G的内存。总共消耗
3分之1的CPU和18分之1的内存。 然后通过DRF的算法最终会给A分配3个CPU+12G内存 给B分配6CPU+2G内存
那么这样的话内阁用户都获得了相同比例的支配性资源,A获得三分之二的内存, B获得三分之二的CPU
单独设置队列内部资源分配方式
FAIR DRF FIFO
Hadoop 的三种调度器图解FIFO、Capacity Scheduler、Fair Scheduler
一、FIFO(先入先出调度器)
hadoop1.x使用的默认调度器就是FIFO。FIFO采用队列方式将一个一个job任务按照时间先后顺序进行服务。比如排在最前面的job需要若干maptask和若干reducetask,当发现有空闲的服务器节点就分配给这个job,直到job执行完毕。
二、Capacity Scheduler(容量调度器)
hadoop2.x使用的默认调度器是Capacity Scheduler。
1、支持多个队列,每个队列可配置一定量的资源,每个采用FIFO的方式调度。
2、为了防止同一个用户的job任务独占队列中的资源,调度器会对同一用户提交的job任务所占资源进行限制。
3、分配新的job任务时,首先计算每个队列中正在运行task个数与其队列应该分配的资源量做比值,然后选择比值最小的队列。比如如图队列A15个task,20%资源量,那么就是15%0.2=70,队列B是25%0.5=50 ,队列C是25%0.3=80.33 。所以选择最小值队列B。
4、其次,按照job任务的优先级和时间顺序,同时要考虑到用户的资源量和内存的限制,对队列中的job任务进行排序执行。
5、多个队列同时按照任务队列内的先后顺序一次执行。例如下图中job11、job21、job31分别在各自队列中顺序比较靠前,三个任务就同时执行。
三、Fair Scheduler(公平调度器)
1、支持多个队列,每个队列可以配置一定的资源,每个队列中的job任务公平共享其所在队列的所有资源。
2、队列中的job任务都是按照优先级分配资源,优先级越高分配的资源越多,但是为了确保公平每个job任务都会分配到资源。优先级是根据每个job任务的理想获取资源量减去实际获取资源量的差值决定的,差值越大优先级越高。
在CDH 中开启Capacity Scheduler容量调度器
1.在ResourceManager中配置它要使用的调度器,配置方式是修改conf/yarn-site.xml,设置属性:
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>
在CM页面中设置的步骤为:
2.在Capacity Scheduler专属配置文件capacity-scheduler.xml,需要说明默认存在root的queue,其他的队列都是它的子队列。
CDH修改
查找参数:yarn.scheduler.capacity.root.queues
默认:
修改之后配置为:
名称: yarn.scheduler.capacity.root.queues
值: default,a
说明: 新建队列名, 划分两个队列, 默认default队列与a队列
名称: yarn.scheduler.capacity.maximum-am-resource-percent
值: 0.5
说明: 集群中用于运行应用程序ApplicationMaster的资源比例上限,该参数通常用于限制处于活动状态的应用程序数目。该参数类型为浮点型,默认是0.1,表示10%。所有队列的ApplicationMaster资源比例上限可通过参数 yarn.scheduler.capacity. maximum-am-resource-percent设置(可看做默认值),而单个队列可通过参数yarn.scheduler.capacity.<queue-path>. maximum-am-resource-percent设置适合自己的值。
名称: yarn.scheduler.capacity.root.default.maximum-capacity
值: 60
说明: 队列最大可使用的资源率。
名称: yarn.scheduler.capacity.root.capacity
值: 100
说明: 它是队列的资源容量占比(百分比)。系统繁忙时,每个队列都应该得到设置的量的资源;当系统空闲时,该队列的资源则可以被其他的队列使用。同一层的所有队列加起来必须是100%。root根节点的资源是100
名称: yarn.scheduler.capacity.root.default.capacity
值: 50
说明: default队列资源为 50
名称: yarn.scheduler.capacity.root.a.capacity
值: 50
说明: a队列资源为 50
名称: yarn.scheduler.capacity.root.default.user-limit-factor
值: 30
说明: 每个用户最多可使用的资源量(百分比)。比如,假设该值为30,则任何时刻,每个用户使用的资源量不能超过该队列容量的30%。
名称: yarn.scheduler.capacity.root.a.user-limit-factor
值: 30
说明: 每个用户最多可使用的资源量(百分比)。比如,假设该值为30,则任何时刻,每个用户使用的资源量不能超过该队列容量的30%。
名称: yarn.scheduler.capacity.root.default.maximum-capacity
值: 50
说明: default队列的资源使用上限(百分比)。由于存在资源共享,因此一个队列使用的资源量可能超过其容量,而最多使用资源量可通过该参数限制
名称: yarn.scheduler.capacity.root.a.maximum-capacity
值: 50
说明: a队列的资源使用上限(百分比)。由于存在资源共享,因此一个队列使用的资源量可能超过其容量,而最多使用资源量可通过该参数限制
名称: yarn.scheduler.capacity.root.default.state
值: RUNNING
说明: 队列状态可以为STOPPED或者RUNNING,如果一个队列处于STOPPED状态, 用户不可以将应用程序提交到该队列或者它的子队列中,类似的, 如果ROOT队列处于STOPPED状态,用户不可以向集群中提交应用程序, 但正在运行的应用程序仍可以正常运行结束,以便队列可以优雅地退出
名称: yarn.scheduler.capacity.root.a.state
值: RUNNING
说明: 队列状态可以为STOPPED或者RUNNING,如果一个队列处于STOPPED状态, 用户不可以将应用程序提交到该队列或者它的子队列中,类似的, 如果ROOT队列处于STOPPED状态,用户不可以向集群中提交应用程序, 但正在运行的应用程序仍可以正常运行结束,以便队列可以优雅地退出
名称: yarn.scheduler.capacity.root.default.acl_submit_applications
值: *
说明: 限定哪些Linux用户/用户组可向给定队列中提交应用程序。需要注意的是,该属性具有继承性,即如果一个用户可以向某个队列中提交应用程序,则它可以向它的所有子队列中提交应用程序。配置该属性时,用户之间或用户组之间用“,”分割,用户和用户组之间用空格分割,比如“user1, user2 group1,group2”。
名称: yarn.scheduler.capacity.root.a.acl_submit_applications
值: *
说明: 同上
名称: yarn.scheduler.capacity.root.default.acl_submit_applications
值: *
说明: 为队列指定一个管理员,该管理员可控制该队列的所有应用程序,比如杀死任意一个应用程序等。同样,该属性具有继承性,
如果一个用户可以向某个队列中提交应用程序,则它可以向它的所有子队列中提交应用程序。名称: yarn.scheduler.capacity.root.a.acl_submit_applications
值: *
说明: 同上
保存配置,之后刷新yarn配置。
结果如下:
注意: 如果是命令行方式修改完成之后需要执行一下命令:
$HADOOP_YARN_HOME/bin/yarn rmadmin -refreshQueues
之后再yarn UI 8088 界面可以看到以划分为两个队列
Yarn 内存分配管理机制及相关参数配置
这篇文章不错。