1、UI界面详解
我们安装完Yarn后,可以在浏览器中通过http://master:8088来访问Yarn的WEB UI,如下图:
我们详细解释上图中标记为1(也就是cluster)和2(也就是Nodes)两个界面中和资源有关的信息
对上面7个字段信息进行解释:
1.Active Nodes:表示Yarn集群管理的节点的个数,其实就是NodeManager的个数,我们集群有2个NodeManager
从配置中可以看到每一个NodeManager管理的内存大小是1630MB,那么整个Yarn集群管理的内存总大小就是1630MB * 2 = 3260MB约等于3.18GB,也就是我们看到的Memory Total
2.Vcores Total:表示Yarn集群管理的cpu的虚拟核心的总数,这个大小等于所有的NodeManager管理的虚拟核心之和,每一个NodeManager管理的虚拟核心数是通过yarn-site.xml中的如下配置进行配置的
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>2</value>
<description>表示这个NodeManager管理的虚拟核心个数</description>
</property>
从配置中可以看到每一个NodeManager管理的虚拟核心数是2,那么整个Yarn集群管理的虚拟核心的总数就是2 * 2 = 4,也就是我们看到的Vcores Total
3.Memory Total:表示Yarn集群管理的内存的总大小,这个内存总大小等于所有的NodeManager管理的内存之和,每一个NodeManager管理的内存大小通过yarn-site.xml中的如下配置进行配置的:
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>1630</value>
<description>表示这个NodeManager管理的内存大小</description>
</property>
4.Scheduler Type:表示资源分配的类型,也就是我Hadoop-yarn安装文章中说到的三中资源调度
5.Minimum Allocation:最小分配资源,就是说当一个任务向Yarn申请资源的时候,Yarn至少会分配<memory:1024, vCores:1>这个资源给这个任务,这个分配的最小内存和最小核心数可以分别由配置yarn.scheduler.minimum-allocation-mb(默认值是1024MB)和yarn.scheduler.minimum-allocation-vcores(默认值是1)来控制
6.Maximum Allocation:最大分配资源,就是说当一个任务向Yarn申请资源的时候,Yarn最多会分配<memory:1630, vCores:2>这个资源给这个任务,这个分配的最大内存和最多核心数可以分别由配置yarn.scheduler.maximum-allocation-mb(默认值是8192MB)和yarn.scheduler.maximum-allocation-vcores(默认值是32)来控制,当然这两个值肯定不能比集群管理的资源还要多
上面是Yarn集群管理的两个NodeManager的状态信息,分别如下:
1.Rack:表示NodeManager所在的机器所在的机架
2.Node State:表示NodeManager的状态
3.Mem Used:表示每个NodeManager已经使用了的内存大小。Mem Avail:表示每个NodeManager还剩多少可以使用的内存大小。VCores Used:表示每个NodeManager已经使用了的VCores数量。VCores Avail:表示每个NodeManager还剩多少可以使用的VCores数量。
点击一个Node Address
进入到如下的界面:
这个界面上的信息是slave2上的NodeManager的详细信息,其中,Total Vmem allocated for Containers表示这个NodeManager管理的虚拟内存的大小,虚拟内存大小由yarn-site.xml中的配置来设置的:
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>4.1</value>
<description>表示这个NodeManager管理的虚拟内存和物理内存大小的比例</description>
</property>
2、yarn集群有时涉及到另一个概念------资源预留
此时 yarn实际的总内存为:Memory Total + Memory Reserved = 所有节点的(Mem Used + Mem Avail)之和
例如上图中:613.13 + 90 = (182 + 52.38)+(193 + 41.38)+(171 + 63.38)约等于 703.13
也等于 Maximum Allocation 的 memory * 节点数 + Memory Reserved
例如上图中:613.13+ 90 = 240000 * 3 / 1024 约等于 703.13
同理,VCores Total 也是一样
资源预留发生在应用向Yarn进行资源申请的时候。yarn的资源预留机制是一种资源保证机制,它发生在应用程序申请的资源无法得到满足的时候。即,当应用程序申请的资源此刻无法满足但是未来只要有一定的资源释放就可以得到满足的情况下,yarn会面临两种选择:
1、优先为这个应用程序预留一个节点上的资源,直到累计释放的空闲资源满足了应用的需求。这种资源的分配方式叫做增量资源分配,即Incremental placement;
2、暂时放弃当前节点资源,直到某个节点的资源一次性满足应用程序的需求。这种分配方式叫做一次性资源分配,即all-or-nothing;
两种分配方式各有优缺点,对于增量资源分配而言,资源预留机制会导致资源浪费,集群资源利用率低,而一次性资源分配虽然在发现资源无法满足某个应用需求的时候及时放弃,但是,这个应用有可能永远得不到自己请求的资源因而永远无法运行,即饿死现象;
因此,yarn最终还是采用了增量资源分配机制,尽管会造成一定的资源浪费,但是不会出现饿死现象,大小应用都有平等的运行机会;
Yarn的一次资源预留,精确来讲,是将 某一个container 在 某个服务器节点上 做资源预留;它发生在服务器节点的可用资源无法满足container所需要的资源的情况下。
注意,请将集群节点资源和队列资源区分开。我们通过队列的配置文件fair-scheduler.xml/capacity-scheduler.xml定义了资源队列,这个队列的资源实际上是对应到各个实际的服务器节点上的内存和CPU资源的。比如,一个队列的容量是100G,代表提交到这个队列的应用所使用的内存最大不可以超过100G,但是,队列对于这些应用具体运行在哪些服务器上、在每台服务器上消耗了多少资源是不限制的,有可能,所有的container都运行在了某一台服务器上,占用了这台服务区100G资源,或者,这些应用运行在了10台服务器上,消耗每台服务器10G资源。
任何一个Yarn应用都提交的container请求如果超过了所在队列的剩余可用资源,这个container是不会被分配也不会被预留的,只有当这个container请求满足其所在队列的剩余资源,却无法在某个节点上运行,才会发生资源预留。
如果我们发现当前服务器节点的剩余资源无法满足这个container的资源请求,这时候就需要为这个container进行资源预留。注意,只有当这个container的资源请求满足队列的剩余可用资源,即,所在队列可用资源能够运行这个container,但是,当前服务器节点的剩余资源却不够用来运行这个container。
因此,如果这个container直接超过了队列的剩余资源,是不会进行资源预留的,直接就分配失败了。
当一个资源被预留的节点上的部分container运行完毕,资源被释放,使得它上面之前进行资源预留的container可以运行了,即,一个container的状态什么时候可以从预留状态转换为运行状态呢?对于连续调度和心跳调度,container状态从RESERVED到ALLOCATED的状态转换都是通过调用FSAppAttemtp.assignReservedContainer()实现的。assignReservedContainer()只是对已经处于预定状态的container进行一次尝试分配,分配可能会失败,如果失败,container依然保持为RESERVED状态。
Yarn的资源预留机制可能在某些情况下造成集群的资源死锁,即,虽然队列有剩余资源,但是,由于单个container请求的资源量较大,所有服务器的剩余资源都无法满足其运行需求,因此发生预留。如果这样的container很多,极端情况下,可能所有服务器都处于预定状态,造成服务器资源死锁,Yarn虽然看似状态正常,但是已经停止服务。这种状态下,我们分析停止服务过程中的日志,不会看到任何异常信息,只有分析停止服务前的日志才能看到原因,即每一个服务器节点都已经被某个container预留,新的 应用提交以后无法申请到资源,而这些预留的container又永远无法摆脱预留状态。
Yarn对预留的处理,只是一种标记,即,将某个服务器标记为被某个container预留。任何一个被某个container预留的服务器,在取消预留或者被预留的container被成功分配之前,这个节点不会为其它container分配资源,只会一次次尝试为这个预留的container分配资源。而正常的没有被预留的服务器节点,则是根据我们定义的优先级(一个资源队列节点的孩子节点之间的优先级、同一个队列节点中应用的优先级、应用内container的优先级)选择出一个资源请求,在这个节点上分配一个container运行这个资源请求。
总之,当集群的资源利用率一直处于较高状态,Yarn的很多边界情况被触发的概率会大大增加,集群会出现较多的奇怪问题,变得非常不稳定。70%或以下左右的平均资源利用率会让集群处于比较好的运行状态。我们的FairScheduler调度器默认使用单一资源调度,进行资源调度的时候不考虑CPU消耗,如果集群负载较多,会经常发生服务器的CPU负载极高,甚至导致服务器宕机。
具体可以参考:
https://blog.csdn.net/zhanyuanlin/article/details/78799341
https://blog.csdn.net/weixin_42411818/article/details/96283995