1、Yarn的架构设计:
这个过程一共是有8个步骤:
1、用户向Yarn中的ResourceManager提交应用程序,其中包括ApplicationMaster程序,启动ApplicationMaster命令、用户命令等。
2、ResourceManager首先为该Application程序分配第一个Container容器,并与对应的Node Manager通信,要求Node Manager在这个Container中启动应用程序的MR ApplicationMaster。
3、ApplicationMaster首先向ApplicationsManager注册,这样用户就可以通过ResourceManager web 8088查看应用程序的运行状态,然后它将为各个任务申请资源,并监控它的运行状态,直到运行结束,即重复步骤4~7。
4、ApplicationMaster采用轮询的方式通过RPC协议向Resource Scheduler申请和领取资源。
5、一旦ApplicationMaster申请到资源后,便与对应的Node Manager通信,要求它启动任务。
6、Node Manager节点为任务设置好运行环境(包括环境变量、JAR包、二进制程序等)后,将任务启动命令写到一脚本中,并通过运行该脚本启动container容器,运行task任务。
7.各个容器的任务,通过某个RPC协议向ApplicationMaster汇报自己的状态和进度,以让ApplicationMaster随时掌握各个任务的运行状态,从而在任务失败时重启任务。在应用程序运行过程中,用户可随时通过RPC向ApplicationMaster通过web界面实时查看应用程序的当前运行状态。
8、应用程序运行完成后,ApplicationMaster向ResourceManager注销并关闭自己。
Container:柜机能运行多少task任务是以Container为单位的,是一个虚拟的概念,是Yarn的资源的抽象,封装了某个节点的多维度资源,如内存,cpu,磁盘,网络等。
当ApplicationMaster向ResourceManager申请资源时,ResourceManage为ApplicationMaster返回的资源就是使用Container来标识,实际上是不存在的。
2、常用命令
hadoop jar
[hadoop@hadoop001 bin]$ yarn
Usage: yarn [–config confdir] COMMAND
where COMMAND is one of:
resourcemanager -format-state-store deletes the RMStateStore
resourcemanager run the ResourceManager
nodemanager run a nodemanager on each slave
timelineserver run the timeline server
rmadmin admin tools
version print the version
jar run a jar file
application prints application(s)
report/kill application
applicationattempt prints applicationattempt(s)
report
container prints container(s) report
node prints node report(s)
queue prints queue information
logs dump container logs
classpath prints the class path needed to
get the Hadoop jar and the
required libraries
daemonlog get/set the log level for each
daemon
top run cluster usage tool
or
CLASSNAME run the class named CLASSNAME
Most commands print help when invoked w/o parameters.
常用这俩个:
yarn application -kill Kills the application.
-list
mapred job -list
-kill job-id
用户习惯使用Yarn,因为Yarn是资源和作业调度平台,不光光运行MapReduce、 Hive 、Spark,MaoReduce命令可能kill不掉 Hive 、Spark的作业。
3、Yarn调优
Container里面包括内存memory和CPU,运行task任务。
内存:先看参数:官网的yarn-default.xml文件,生产上的内存的调优就是以下3组参数的值分配:
yarn.nodemanager.resource.memory-mb 8192
yarn.scheduler.minimum-allocation-mb 1024
yarn.scheduler.maximum-allocation-mb 8192
举个例子:
生产上一台服务器48G内存,在分配机器分别运行哪些进程时首先预留25%(12G)的内存给Linux,剩下的75%(36G)的内存给大数据进程。正常企业里面大数据进程是要部署的,正常是需要进行计算的,Yarn的进程部署过程中DataNode(数据存储节点)和NodeManager(计算节点)进程是部署在同一个机器上面,即数据本地化,什么是数据本地化?假如DataNode和NodeManager分别部署在不同的机器上,NodeManager进行计算时需要向存储数据DataNode的机器去拉取数据,要通过网络IO(网络带宽)进行,速度肯定会降低,并且占用网络带宽。假如DataNode和NodeManager分别部署在同一的机器上,NodeManager进行计算时不需要通过网络IO直接在本台机器上拉取数据,速度肯定会快。(存储和计算分离)
生产上面DataNode不是越大越好,生产上一般设置DataNode为4G,在etc/hadoop/hadoop-env.sh脚本中设置:
Export HADOOP_DATANODE_OPTS="-Dhadoop.security.logger=ERROR,RFAS $HADOOP_DATANODE_OPTS"
export HADOOP_DATANODE_OPTS="-Xms2048m -Xmx2048m $HADOOP_DATANODE_OPTS"
设置完之后需要重启生效,这时DataNode的内存就修改为相对应的容量。
生产上面同样也可以修改NodeManager的内存,一般设置为3G的内存,在etc/hadoop/yarn-env.sh脚本里面修改:
YARN_OPTS="$YARN_OPTS -Xms2048m -Xmx2048m"
设置完之后也要重启生效,这时NodeManager的内存就修改为相对应的容量。
从上面可以了解到hdfs默认的内存是1000m,1G内存都不到,放在生产环境下面可能内存就不够了,所以需要根据实际情况重新给hdfs加内存。
如此分配之后,还剩下36-4-3=29G的内存是分配给Container容器的,yarn.nodemanager.resource.memory-mb yarn.scheduler.minimum-allocation-mb 和yarn.scheduler.maximum-allocation-mb这3个参数就是设置Container容器的内存的,生产上面对这3个参数的设置是非常巧妙的,例如将内存平均分配给多个容器,尽管每个容器内存容量比较小,但是所有的容器并行运行所有的任务,往往会比单一容器运行或分配少量容器较多内存运行任务的速度快。
生产上面有一个不成文的规定,scheduler是Container容器的调度,nodemanager.resource是管理所有的Container容器,官方设定单个容器yarn.scheduler.minimum-allocation-mb最小内存容量是1G,yarn.scheduler.maximum-allocation-mb最大内存容量是8G,一个Container容器刚开始申请资源时是1G内存,在计算过程中数据越来越多,迭代越来越多,发现需要更多的内存时就会慢慢地涨内存,当自动涨到达到所设定的最大内存容量的时候,就是抛错OOM,所以生产上是不会这么设定的,生产上是将最小的内存容量设置为2G,最大的内存容量设置为yarn.nodemanager.resource.memory-mb参数相等的内存,即为单个容器所占有的全部内存大小,是为了防止单个容器使用时内存暴增,最大限度地充分利用内存空间。
如果内存超出了,需要设置参数控制内存超出时把进程杀死,即:
yarn.nodemanager.pmem-check-enabled=true:物理内存强制限制Container容器,Container容器超出物理内存时会自动检查并kill掉容器 其任务也会被kill掉
yarn.nodemanager.vmem-check-enabled=true
很多时候会谈到虚拟内存:yarn.nodemanager.vmem-pmem-ratio=2.1 :虚拟内存1m pvmen=2.1m vmen
CPU:
CPU时运行Task的,生产上引出一个vcore:虚拟CPU的core,是yarn自己引入的新概念,考虑到不同节点上的CPU性能,每台机器CPU性能不一样,不同机器的core是不一样的,性能也不一样,所以引入vcore的概念。
1个物理CPU的core正常对应的是2个vcore,有些是1个,通过为物理CPU多配置几个虚拟的vcore是为了弥补性能的差异,使得运行任务计算性能更为统一。用户提交作业时可以指定任务需要的虚拟CPU的个数,但是这种情况在Spark中比较常见。
配置CPU同样也有3组参数:
yarn.nodemanager.resource.cpu-vcores =12
yarn.scheduler.minimum-allocation-vcores=1
yarn.scheduler.maximum-allocation-vcores=12
生产上如果你的机器是8个物理core,预留2个core给其他进程,则有6个物理core,衍生出12个vcore用于生产CPU运行任务,官方给出物理CPU的虚拟vcore的最大个数是8个,最小是1个,通常将yarn.nodemanager.resource.cpu-vcores 参数值和yarn.scheduler.maximum-allocation-vcores参数值设置一致,这样在运行任务比较多的情况下,vicore能自动增长到最大值。
4、Yarn的三种调度器
在Yarn中有3种调度器可以选择:
(1)FIFO Scheduler:把应用按照提交的顺序排成一个队列,这是一个先进先出的队列,在进行资源分配的时候,先给队列中最头上的应用进行分配资源,待最头上的应用需求满足后再给下一个分配,以此类推。这种调度器的小任务会被大任务阻塞。
FIFO Scheduler是最简单也是最容易理解的调度器,也不需要任何配置,但它并不适用于共享集群。大的应用可能会占用所有集群资源,这就导致其他资源被阻塞。
(2)Capacity Scheduler:计算调度,有一个专门的队列Queen B运行小任务,大任务Queen A队列,大任务还是小任务都是由Yarn识别,两个队列的运行互不影响,但是小任务专门设置一个队列会预先占用一定的集群资源,这就导致大任务的执行时间会落后于使用FIFO Scheduler调度器时的时间。
(3)FairScheduler:公平调度,小任务需要事先占用一定的系统资源,FairScheduler公平调度会为所有运行的job动态地调整系统的资源。当中途有新的任务需要运行时,会将之前运行完的资源释放出来给新的任务运行,同时自己也还在运行,当新任务运行完成之后,释放了资源,这部分资源又可以重新用于自身的运行,这样既保证了资源的高度利用,又保证了小任务的及时完成。
需要注意的是在FairScheduler调度器中,从第二个任务提交到获得资源会有一定的延迟,因为它需要等待第一个任务释放占用的Container,小任务执行完成之后也会释放自己占用的资源,大任务又重新获得了全部的系统资源。
在共享集群中,更适合采用Capacity Scheduler或FairScheduler,这两个调度器都允许大任务和小任务的在提交的同时获得一定的系统资源。