本节分为三部分:
1.YARN架构设计
2.YARN生产上资源管理--生产调优参数配置
3.YARN生产上调度器
YARN :Yet Another Resource Negotiator
1.YARN架构设计
(和上一篇的MapReduce其实是一样,在这里再过一遍)
(当面试的时候,问到 MapReduce job执行流程、MapReduce on yarn架构、 yarn架构设计的时候,这三个问题实际上是同一个问题。)
参考官网:hadoop.apache.org 多读读里面写的过程。
MapReduce状态、job提交、节点状态、资源请求。
ResourceManager里面包括:Applications Manager应用程序管理器和 Resource Scheduler资源调度器。
App Master:指的是用户提交的应用程序的主程序,主要负责程序的监控、跟踪状态、重启我们失败的任务。
‘这里不再多说,参照上一篇博客。
2.YARN生产上资源管理 至关重要的---yarn的资源调优☆☆☆
参照这张图:
①内存方面:
假如一台机器是48G物理内存,一般8个物理core,对应的16个虚拟core(16vcore)(新版本默认
的是1:1,是8vcore,如果设置的话,记得改参数)
Linux系统本身要占内存+空留: 20% =9.6G (生产上一般20%--30%都是可以的)
(当机器内存剩余的特别少的时候,有些操作系统会触发OOM killer的机制,把使用内存最大的
进程给kill掉,所以要有剩余的内存,让机器有些缓冲。)
剩余: 80% =38.4G=38G (这80%就是给大数据用的组件、部署的进程所使用的,因为是主从架
构,都是小弟干活,小弟占的最多)
②
如何设置nn、dn、rm、nm这几个组件所要求的分配的内存的大小?如下:
DataNode进程: 生产4G (并不是越多越好)
默认是1000m
hadoop-env.sh
HADOOP_NAMENODE_OPTS=-Xmx1024m
HADOOP_DATANODE_OPTS=-Xmx1024m
NodeManager进程: 生产4G
yarn-env.sh
export YARN_RESOURCEMANAGER_HEAPSIZE=1024
export YARN_NODEMANAGER_HEAPSIZE=1024
(正常情况下,DataNode进程和NodeManager进程部署在同一台机器: 数据本地化
比如:在NM上运行task任务,task任务需要数据,数据是放在当前机器的hdfs上面的,发现当前
有DataNode进程,节点上有需要的数据,那就只需要从当前节点拿数据就行了。但是如果发现当
前机器上没有数据,要去另外的机器上拿数据,那就会通过网络,这时候会网络消耗,计算就会
变慢了。)
(NN RM 经常性部署同一台 说白了 因为集群节点少,也就100多台。也可以不是同一台)
③
资源内存: 38G-4-4=30G (这30G是做什么?就是运行container容器)
yarn.nodemanager.resource.memory-mb 这里我们是设置30*1024 (这是总的大小)
yarn.scheduler.minimum-allocation-mb 官方默认1024 (最小可分配容器的大小)
yarn.scheduler.maximum-allocation-mb 官方默认8192 (最大可分配容器的大小)
(分配的容器的大小就是根据上面的参数来进行分配的)
30G 30G/1G=30个container (总共30G,如果全是最小的容器,就是30个容器)
30G 30/8=3个container ...6G (总共30G,如果全是最大的容器,就是3个容器,还有6G浪费了)
30个~3个 这台机器可以运行3-30个容器。生产上可以这样吗?最好是可以整除。
那么生产上面怎么设置呢?
生产一(大作业的环境):
yarn.nodemanager.resource.memory-mb 30G
yarn.scheduler.minimum-allocation-mb 2G
yarn.scheduler.maximum-allocation-mb 30G
(这个是大作业的情况。要看每个公司的作业情况,如果作业特别大的情况,就设成和总的一样
大)
容器最小2G,就是这台机器最多可以运行15个容器,容器最大30G,就是这台机器最多可以运行1
个容器。那这台机器可以运行1-15个容器。
当你去请求资源的时候,它先给你分配一个最小的值,比如说2G,然后你如果不够,给你加比如
说1G,直到加到最大比如说30G。(这个是有参数可以去配置的,在hadoop官网没有,在cdh官网
是可以找到的)
生产二(小作业的环境):
yarn.nodemanager.resource.memory-mb 32G (这个由30G调整到32G,就需要从预留的20%里面
拿出2G出来。这样32/8=4个容器,可以整除,不会浪费了)
yarn.scheduler.minimum-allocation-mb 2G
yarn.scheduler.maximum-allocation-mb 8G
16c~4c
生产三:
服务器是256G(还有其它进程,比如hbase、kafka、zookeeper等,所以只放出60%的资源给它)
yarn.nodemanager.resource.memory-mb 168G
yarn.scheduler.minimum-allocation-mb 4G
yarn.scheduler.maximum-allocation-mb 24G
④
一个容器它使用的是物理内存,如果它使用超的话,默认情况下,会把它kill掉。这是由参数去
控制的。(oom:out of memory)
生产默认(生产上尽量都要开着,生产不去修改,都是默认):
yarn.nodemanager.pmem-check-enabled true (nm检查容器物理内存)
yarn.nodemanager.vmem-check-enabled true (nm检查容器虚拟内存)
yarn.nodemanager.vmem-pmem-ratio 2.1 (物理内存与虚拟内存比率)
物理内存如果是1G,那么虚拟内存就是2.1G
两个中,哪一个超出了设定的值,就会把它kill掉。
⑤
新版本参数
yarn.nodemanager.resource.pcores-vcores-multiplier 1 (老的是2,现在是1,需要手动把它修改成2)
yarn.nodemanager.resource.memory-mb
yarn.scheduler.minimum-allocation-mb
yarn.scheduler.maximum-allocation-mb
这些参数的需要看官网里的默认配置yarn-default.xml。
比如:yarn.nodemanager.resource.memory-mb如果设置成-1:
Amount of physical memory, in MB, that can be allocated for containers. If set to -1and yarn.nodemanager.resource.detect-hardware-capabilities is true, it is automatically calculated(in case of Windows and Linux). In other cases, the default
is 8192MB.
yarn.nodemanager.resource.detect-hardware-capabilities:Enable auto-detection of nodecapabilities such as memory and CPU.(默认是false)
⑥
CPU方面: (pcore物理core vcore虚拟core)
yarn.nodemanager.resource.cpu-vcores 12(总共16个(8个pcore),只拿出了12个(6个pcore))
yarn.scheduler.minimum-allocation-vcores 1
yarn.scheduler.maximum-allocation-vcores 4
(core不会像内存那样,如果不够还会再申请加内存,它申请了之后,就不会再涨了)
container: 2G 3c
问题:一个容器既有内存,又有CPU,那么内存和CPU分配的数量,是不是要接近于相等?是的
yarn.nodemanager.resource.memory-mb 32G
yarn.scheduler.minimum-allocation-mb 2G
yarn.scheduler.maximum-allocation-mb 8G
(从这个可以看出来,可以启用32/2=16,32/8=4,也就是可以启用4-16个容器)
yarn.nodemanager.resource.cpu-vcores 12
yarn.scheduler.minimum-allocation-vcores 1
yarn.scheduler.maximum-allocation-vcores 4
(从这个可以看出来,可以启用12/1=12,12/4=3,也就是可以启用3-12个容器)
container:
memory 16container~4container
vcores 12container~3container
生产上,需求肯定是要取最大的,16到4个容器,但是按照上面来说,容器的最终个数是上面最小
的来决定的,就是12到3个容器。如果你想要用4个容器,这个时候就用不了,那另外的8个G的内
次你就浪费了。如果你想要调到最大,你就需要适当的调整这些参数,说白了就是资源最大化。
比如下面设置成:
yarn.nodemanager.resource.cpu-vcores 16
yarn.scheduler.minimum-allocation-vcores 1
yarn.scheduler.maximum-allocation-vcores 4
这样是可以的,vcores就是16c~4c了,和memory一样了。
很多人做了多年的大数据,都不知道这种情况。
(上面是理想情况,不过发生这种情况还是很多的)
⑦
看博客:YARN的Memory和CPU调优配置详解
⑧面试题:
【若泽大数据实战第十四天】YARN 生产详解_强悍de巨人的博客-CSDN博客
3.调度器 (面试题)
理想情况下,我们应用对Yarn资源的请求应该立刻得到满足,但现实情况资源往往是有限的,特别是在一个很繁忙的集群,一个应用资源的请求经常需要等待一段时间才能的到相应的资源。在Yarn中,负责给应用分配资源的就是Scheduler。其实调度本身就是一个难题,很难找到一个完美的策略可以解决所有的应用场景。为此,Yarn提供了多种调度器和可配置的策略供我们选择。
在Yarn中有三种调度器可以选择:FIFO Scheduler ,Capacity Scheduler,FairScheduler。
大作业小作业是由谁来决定的,是由Applications manager来决定的。
FIFO Scheduler把应用按提交的顺序排成一个队列,这是一个先进先出队列,在进行资源分配的时候,先给队列中最头上的应用进行分配资源,待最头上的应用需求满足后再给下一个分配,以此类推。
FIFO Scheduler是最简单也是最容易理解的调度器,也不需要任何配置,但它并不适用于共享集群。大的应用可能会占用所有集群资源,这就导致其它应用被阻塞。在共享集群中,更适合采用Capacity Scheduler或Fair Scheduler,这两个调度器都允许大任务和小任务在提交的同时获得一定的系统资源。在FIFO 调度器中,小任务会被大任务阻塞。
而对于Capacity调度器,有一个专门的队列用来运行小任务,但是为小任务专门设置一个队列会预先占用一定的集群资源,这就导致大任务的执行时间会落后于使用FIFO调度器时的时间。这个专门的队列不管有没有小任务运行,它都会一直占着资源,这样会造成资源的浪费。
在Fair调度器中,我们不需要预先占用一定的系统资源,Fair调度器会为所有运行的job动态的调整系统资源。当第一个大job提交时,只有这一个job在运行,此时它获得了所有集群资源;当第二个小任务提交后,Fair调度器会分配一半资源给这个小任务,让这两个任务公平的共享集群资源。
需要注意的是,在Fair调度器中,假如第一个任务很大提交了,过了一段时间,第二个任务很小也提交了,从第二个任务提交到获得资源会有一定的延迟,因为它需要等待第一个任务task释放占用的Container。小任务执行完成之后也会释放自己占用的资源,大任务又获得了全部的系统资源。最终的效果就是Fair调度器即得到了高的资源利用率又能保证小任务及时完成。
调度器参考:Yarn 调度器Scheduler详解 - gongxiucheng - 博客园
’
调度器具体怎么配置,不用关心,扩展知识。生产上是用CDH的。(生产真的用apache的,就参照官网的去配置,或者Google一下,比如谷歌上:https://netjs.blogspot.com/2018/04/fair-scheduler-in-yarn-hadoop.html)
生产上CDH下载:https://www.cloudera.com/downloads/manager/6-1-1.html
CDH有动态资源池,里面有放置规则。(面试)
放置规则 比如:
<queuePlacementPolicy>
<rule name="specified" />
<rule name="primaryGroup" create="false" />
<rule name="default" queue="ABC"/>
</queuePlacementPolicy>
<?xml version="1.0"?>
<allocations>
<queue name="ABC">
<minResources>10000 mb,10vcores</minResources>
<maxResources>60000 mb,30vcores</maxResources>
<weight>2.0</weight>
<schedulingPolicy>fair</schedulingPolicy>
</queue>
<queue name="XYZ">
<minResources>20000 mb,0vcores</minResources>
<maxResources>80000 mb,0vcores</maxResources>
<weight>3.0</weight>
<schedulingPolicy>fifo</schedulingPolicy>
</queue>
<queueMaxResourcesDefault>40000 mb,20vcores</queueMaxResourcesDefault>
<queuePlacementPolicy>
<rule name="specified" />
<rule name="primaryGroup" create="false" />
<rule name="default" queue="ABC"/>
</queuePlacementPolicy>
</allocations>