1.简述
Yarn是Hadoop2.X的核心组件之一.负责集群的资源管理.(不局限于Hadoop,Spark等等相当多的组件都可以利用Yarn来进行资源管理与调度)
Yarn本身由两大组件构成:ResourceManager(RM)和NodeManager(NM).在Yarn中,整个资源管理依靠这两大组件来共同完成.
ResourceManager:
ResourceManager负责整个集群的资源管理与分配.它本身再由两个组件构成
应用程序管理器ApplicationManager
ApplicationManager是RM的中心入口,负责管理整个集群的应用程序.包括应用程序的提交,与调度器协商资源,跟踪分配的Container,启动AppMaster,监控AppMaster执行状态,失败重启等等
调度器(Scheduler)
调度器根据根据队列,容量等等条件(比如每队最多分配多少,最多执行作业数多少),总体上将系统中的资源分配给各个应用程序.
对于某一个应用程序,根据对该应用程序的请求进行资源分配.
资源分配的最终结果是一个Container.
NodeManager
NodeManager是每个节点上的资源管理器和任务管理器.它会定时向RM汇报本节点的资源情况和各个Container的运行状态,并接收和实际处理来自ApplicationManager的Container启动&暂停命令
2.一些核心概念
2.1 Container与资源隔离
Container,意义就像它的名字-容器.它是Yarn中对资源的一种抽象.它封装的是某个节点的多维度资源(内存,CPU,磁盘,网络等等),也是资源最终分配的结果与单位,
Container作为容器的另一个概念就是资源隔离.
资源隔离包含两层含义,即
Container之内的运行使用资源的上限不会超过Container,
Container之外的运行不会占用到Container之内的资源.
Container资源隔离的实际操纵者,是Yarn的NM.它针对不同的资源,可以使用不同的隔离机制.具体见后
2.2 ApplicationMaster
ApplicationMaster是一种应用框架,这是Yarn跨越Hadoop可以作为很多框架的资源调度组件的基础.
ApplicationMaster可以是任何编程语言编写的程序,它使用ProtocolBuf和ResourceManager.NodeManager进行交互.
它实际负责向ResourceManager申请协调资源,并且与NodeManager协同工作完成对任务的执行,监控等等(跟踪应用程序状态重启失败任务).
它的原生支持就是MR,但比如Spark,Storm等等很多都实现了自己的ApplicationMaster,所以才可以譬如SparkOnYarn.
3.Yarn的工作流程
1.向Yarn提交一个应用程序.(这个应用程序本身就会包含几个部分:用户程序,ApplicationMaster程序,以及启动ApplicationMaster的命令等)
2.ResourceManager将会为这个应用程序分配第一个Container.并且会立即与这个Container所在的NodeManager通讯,要求以这个Container启动ApplicationMaster应用程序
3.ApplicationMaster被启动后,会首先向ResourceManager注册,这个时候应用程序已经正式启动,可以通过ResourceManager查看应用程序状态了.
之后ApplicationMaster将接管应用程序,负责与ResourceManager通讯为之后的各个任务申请资源,监控状态,重复以下4-7步骤直到整个任务结束
4.ApplicationMaster采用轮询的方式通过RPC协议向ResourceManager申请资源
5.一旦申请到资源拿到Container,ApplicationMaster将会立即与Container所在的NodeManager通讯,要求它启动任务
6.NodeManager为任务设置好运行环境(包括环境变量,Jar包,二进制程序等等),将任务启动写到一个脚本里,然后执行脚本启动任务
7.各个任务通过RPC协议向ApplicationMaster汇报自己的状态和进度,以便ApplicationMaster随时重启某个任务
8.任务全部结束后,ApplicationMaster向ResourceManager注销并关闭自己
4.Yarn的资源隔离机制
Yarn的资源都是指可供使用的资源,比如应该刨除操作系统本身占用,其它应用程序占用等,Yarn本身不会智能探测节点的资源
4.1 内存隔离
Yarn的内存隔离默认是采用线程监控是否超量.一旦发现超量会立即杀死任务.
Java进程在创建之初内存会暴增然后迅速回复正常,所以采用线程监控会更加合适.Cgroups机制是任何时候都不得超量,这样很容易在进程启动之初被杀死
Yarn的内存相关配置
yarn.nodemanager.resource.memory-mb Yarn上可使用的物理内存,默认8192(MB),如果节点内存资源不足,则应酌情减少这个值(Yarn本身不会智能探测节点的内存总量)
yarn.nodemanager.vmem-pmem-ratio 任务每使用1MB物理内存,则可以使用多少虚拟内存.默认2:1
yarn.nodemanager.pmem-check-enabled 是否启动一个线程检查每个任务的物理内存使用量,如果超过分配值,则将其杀死.默认为true
yarn.nodemanager.vmem-check-enabled 是否启动一个线程检查每个任务的虚拟内存使用量,如果超过分配至,则将其杀死,默认为true
yarn.scheduler.minimum-allocation-mb 单个任务可申请的最少内存量,默认1024(MB)
yarn.scheduler.maximum-allocation-mb 单个任务可申请的最大内存量,默认8192(MB)
4.2 CPU隔离
在Yarn中,因为考虑到不同的CPU的计算性能差别极大,CPU资源被重新定义了一个虚拟CPU的概念.对于高性能CPU,可以配置更高的虚拟CPU配比率.
默认情况下,Yarn不会对CPU进行调度,需要使用专门的资源管理器
Yarn的CPU相关配置
yarn.nodemanager.resource.cpu-vcores 表示该节点可使用的虚拟CPU个数,默认为8,建议配置为物理核数,高性能CPU可以配置为2倍物理核数
yarn.scheduler.minimum-allocation-vcores 单个任务申请的最少核数,默认为1
yarn.scheduler.maximum-allocation-vcores 单个任务申请的最大核数,默认为32
5.Yarn的资源调度策略
理想情况下,我们对Yarn的资源申请应该立即得到满足,但实际情况下整个集群的资源总量是有限的,这时就依赖资源调度器对资源进行调度了.
但在实际过程中,资源的调度策略本身就是一个难题,很难有一个完美的调度策略可以适用与所有的情况,为此Yarn提供了三种调度器让我们自行选择适用
5.1 FIFO调度器
这种调度会把所有资源申请放入一个队列先进先出.这是最简单的调度,也不需要任何配置,但这种调度器不适用共享集群环境.原因很简单,先入的大任务,会卡死后面的资源申请.
5.2 Capacity调度器
5.2.1 Capacity调度说明
这种调度运行多个组织共享集群,每个组织都可以获得集群的一部分计算能力.
通过为每一个组织都设置一个队列,再为每个队列都分配一定的集群资源,这样集群就可以为多个组织同时提供服务了.
在每个队列之内,资源将进行垂直划分,这样每个组织的成员将可以共享队列内部的资源.但在队列内部,依然是先进先出策略.
如果某个组织的资源已经全部用完而又急需分配,Yarn可能会将其它队列资源分配给它,这就是弹性队列,这时需要为队列设置一个最大资源使用量,防止抢夺太多的空闲资源
5.2.2 Capacity使用说明
假设有如下的组织层次
root
├── prod
└── dev
├── eng
└── science
下面是一个简单的Capacity配置文件,文件名 capacity-scheduler.xml
在这个配置中,在root队列下面定义了两个子队列prod
和dev
,分别占40%和60%的容量。
需要注意,一个队列的配置是通过属性yarn.sheduler.capacity.<queue-path>.<sub-property>
指定的
<queue-path>
代表的是队列的继承树,如root.prod
队列
<sub-property>
一般指capacity
和maximum-capacity
。
可以看到,dev
队列又被分成了eng
和science
两个相同容量的子队列。dev
的maximum-capacity
属性被设置成了75%,所以即使prod
队列完全空闲dev
也不会占用全部集群资源,也就是说,prod
队列仍有25%的可用资源用来应急。我们注意到,eng
和science
两个队列没有设置maximum-capacity
属性,也就是说eng
或science
队列中的job可能会用到整个dev
队列的所有资源(最多为集群的75%)。而类似的,prod
由于没有设置maximum-capacity属性,它有可能会占用集群全部资源。
Capacity容器除了可以配置队列及其容量外,我们还可以配置一个用户或应用可以分配的最大资源数量、可以同时运行多少应用、队列的ACL认证等
5.3 Fair调度器
这种调度不需要预先占用资源.Fair调度器会为所有Job动态的分配资源.
比如第一个任务提交时,如果任务要求的非常多,调度器甚至会将全部的资源都分配给该Job,而当第二个Job申请时,调度器会将一部分Job1释放的资源不再继续给与Job1,而分配个Job2,以此类推
这种所有的任务都能获得一定量的资源得以运行,但注意比如Job2的申请,此时会有等待,因为它必须等到Job1的某些任务完毕释放后才能获得分配
https://blog.csdn.net/suifeng3051/article/details/49508261