1、什么是yarn
1.hadoop集群是将多台机器联合起来,成为一个大的集群服务器
2.每台机器的硬盘,提供出来组成hdfs分布式文件系统
3.每台机器的CPU和MEM内存由yarn管理调度
2、yarn架构解析
类似于hdfs,yarn也是主从架构(master/slave),由一个ResourceManager和多个NodeManager组成
1.ResourceManager为主节点:保证yarn集群正常运行,管理整个yarn集群(包括nodemanager的上线和下线),接收客户端提交的任务
2.NodeManager为从节点:提供资源(CPU及MEM),用于执行分布式任务计算
2.1 ResourceManager
ResourceManager是yarn中的master
rm是一个全局的资源管理器,集群只有一个active的对外服务
1.负责整个系统的和资源管理和分配
2.包括处理客户端请求
3.启动/监控applicationMaster
4,监控NodeManager,资源的分配与调度
它有两个组件:调度器Scheduler和应用程序管理器ApplicationManager ASM
2.2 NodeManager
NodeManager是yarn中的slave
1.当一个节点启动时,它会向ResourceManager进行注册并告知ResourceManager自己有多少资源可用
2.每个计算节点,运行一个NodeManager进程,通过心跳(每秒)yarn.resourcemanager.nodemanagers.heartbeat-interval-ms, 上报节点的资源状态(磁盘,内存,CPU等使用信息)
功能:
1.接收来自ResourceManager的命令,分配Container给应用的任务
2.监控本节点资源和各个Container的运行状态(CPU&MEM等)
3.监控并报告Container使用信息给ResourceManager
4.定时向ResourceManager发送心跳信息,确保存活
5.处理来自ApplicationMaster的请求
6.管理所在节点每个Container的生命周期
2.3 Container
Container是Yarn中资源的抽象
1.yarn以container为单位分配资源
2.它封装了某节点的多维度资源,比如内存,CPU,磁盘,网络等
Yarn会为每个任务分配一个Container,该任务只能使用这个Container中指定的资源
Container和集群NodeManager节点的关系:
1.一个NodeManager可以运行多个Container
2.一个Container不会跨节点
3.任何一个job必须执行在一个或多个Container汇总
4.Yarn中,ResourceManager只负责告诉ApplicationMaster那些Containers可以用
5.ApplicationMaster还需要找NodeManager请求分配具体的Container
需要注意的是:
1.Container是一个动态资源划分单位,是根据应用程序需求动态生成的
2.目前Yarn仅支持CPU和内存两种资源,且使用了轻量级资源隔离机制Cgroups进行资源隔离
功能:
1.对task环境的抽象
2.描述一系列信息
3.运行资源的集合(内存,CPU,IO等)
4.任务运行环境
2.4 ApplicationMaster
功能:应用程序管理器
1.获得数据分片
2.为应用程序申请资源并进一步分配给内部任务Task
3.任务监控与容错
4.负责协调来自ResourceManager的资源,并通过NodeManager监控Container的执行和资源使用情况
ApplicationMaster与ResourceManager之间通信:
1.是yarn从任务提交到运行的最核心部分,是Yarn对集群进行动态资源管理的基本步骤
2.appMaster定期向Rm发送心跳,保证存活
3.Yarn的动态性,就是来源于多个Application的APPMaster动态的和RM进行沟通,不断的申请释放,再申请再释放的过程
2.5 JobHistoryServer
作业历史服务
第一步:修改mapred-site.xml
cd /opt/module/hadoop-2.7.3/etc/hadoop
vim mapred-site.xml
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop003:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop003:19888</value>
</property>
第二步:修改yarn-site.xml
vim yarn-site.xml
<!-- 开启日志聚合功能,将application 运行时,每个container的日志聚合到一起保存到文件系统,一般是HDFS-->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- 多长时间删除一次产生的聚合日志 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>2592000</value><!--30 day-->
</property>
<!-- 保留日志多少秒,只有日志聚合功能关闭时才有效yarn.1og-aggregation-enabie,现在已经开启
<property>
<name>yarn.nodemanager.log.retain-seconds</name>
<value>604800<value>
</property>-->
<!-- 指定聚合产生的日志压缩算法 -->
<property>
<name>yarn.nodemanager.log-aggregation.compression-type</name>\
<value>gz</value>
</property>
<!-- nodemanager本地文件存储目录 -->
<property>
<name>yarn.nodemanager.1ocal-dirs</name>
<value>/opt/module/hadoop-2.7.3/data/yarn/local</value>
</property>
<!-- resourceManager 保存完成任务的最大个数 -->
<property>
<name>yarn.resourcemanager.max-completed-applications</name>
<value>1000</value>
</property>
<property>
<name>yarn.log.server.url</name>
<value>http://hadoop1:19888/jobhistory/1ogs</value>
</property>
第三步:分发修改后的文件
scp yarn-site.xml mapred-site.xml hadoop002:`pwd`
scp yarn-site.xml mapred-site.xml hadoop003:`pwd`
第四步:重启Yarn和Jobhistory服务
cd /opt/module/hadoop-2.7.3/sbin
./stop-yarn.sh
./start-yarn.sh
hadoop2.X:
mr-jobhistory-daemon.sh stop historyserver
mr-jobhistory-daemon.sh start historyserver
hadoop3.X:
mapred --daemon stop historyserver
mapred --daemon start historyserver
jps
#执行MapReduce任务测试
hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar pi 10 10
2.6 Timeline Server
-
用来写日志服务数据,一般来写与第三方结合的日志服务数据(比如spark)
-
它是对jobhistoryserver功能的有效补充,jobhistoryserver只能对mapreduce类型的作业信息进行记录
-
它记录除了jobhistoryserver能够对作业运行过程中信息进行记录之外,还记录更细粒度的信息,比如任务在哪个队列中运行,运行任务时设置的用户是哪个用户
-
timelineserver功能更强大,但不是替代jobhistory两者是功能间的互补关系
3、Yarn应用运行原理
3.1 Yarn应用提交过程
- Application在yarn中的执行过程,整个执行过程可以总结为三步
- 应用程序提交
- 启动应用的ApplicationMaster实例
- ApplicationMaster实例管理引用程序的执行
- 客户端提交一个人物给resourceManager
- ResourceManager接收客户端提交的任务
- RM找一台NodeManager启动一个Container, Container用于运行ApplicationMaster, ApplicationMaster负责客户端提交的任务调度
- APPMaster向resourcemanager申请资源,ResourceManager与NodeManager通信,NM启动Container提供资源
- ResourceManager通知APPMaster启动的Container位置
- APPMaster通知Container执行MapTask或ReduceTask
3.2 MapReduce on Yarn
3.3 Yarn应用生命周期
1.Client向RM提交应用,包括AM程序及启动AM的命令
2.RM为AM分配第一个容器,并与对应的NM通信,令其在容器上启动应用的AM
3.AM启动时向RM注册,允许Client向RM获取AM信息然后直接和AM通信
4.AM通过资源请求协议,为应用协商容器资源
5.如容器分配成功,AM要求NM在容器中启动应用,应用启动后可以和AM独立通信
6.应用程序在容器中执行,并向AM汇报
7.在应用执行期间,Client和AM通信获取应用状态
8.应用执行完成,AM向RM注销并关闭,释放资源
申请资源->启动appMaster->申请运行任务的container->分发Task->运行Task->Task结束->回收container
4、Yarn调度器
4.1 资源调度器的功能
资源调度器是yarn最核心组件之一,负责整个集群资源管理和分配,yarn提供了三种调度器FIFO, Capacity Scheduler, Fair Scheduler
4.2 三种调度器的介绍
1.先进先出调度器FIFO
- 按顺序执行,FirstIn FirstOut
- 如果有个大任务执行,小任务在后面,会先执行完大任务才会执行小任务
- 在FIFO调度器中,小任务可能被大任务阻塞
2.容量调度器Capacity Scheduler
- Capacity 调度器允许多个组织共享整个集群,每个组织可以获得集群的一部分计算能力。通过为每个组织分配专门的队列,然后再为每队列分配一定的集群资源,这样整个集群就可以通过设置多个队列的方式给多个组织提供服务了。除此之外,队列内部又可以垂直划分这样一个组织内部的多个成员就可以共享这个队列资源了,在一个队列内部,资源的调度是采用的是先进先出(FIFO)策略。
3.公平调度器Fair Scheduler
-
支持多队列多用户,每个队列的资源量可以配置,同一队列中的作业公平共享队列中的所有资源
-
比如有三个队列QA,QB,QC, 每个队列中的job按照优先级分配资源,优先级越高分配的资源越多,但是每个job都会分配到资源确保公平
-
在资源有限的情况下,每个job理想情况下获得的计算资源与实际获得的计算资源存在一种差距,这个差距就叫做缺额。在同一个队列中,job的资源缺额越大,越先获得资源优先执行。作业是按照缺额的高低来先后执行的,而且可以看到上图有多个作业同时运行
4.3 自定义队列,实现任务提交不同队列
查看默认提交方案
-
前面我们看到了hadoop当中有各种资源调度形式,当前hadoop的任务提交,默认提交到default队列里面去了,将所有的任务都提交到default队列,我们在实际工作当中,可以通过划分队列的形式,对不同的用户,划分不同的资源,让不同的用户的任务,提交到不同的队列里面去,实现资源的隔离
-
资源隔离目前有2种,静态隔离和动态隔离。
- 所谓静态隔离是以服务隔离,是通过cgroups (LINUX control groups) 功能来支持的。比如HADOOP服务包含HDFS,HBASE,YARN等等,那么我们固定的设置比例,HDFS:20%,HBASE:40%,YARN: 40%,系统会帮我们根据整个集群的CPU,内存,IO数量来分割资源,先提一下,IO是无法分割的,所以只能说当遇到IO问题时根据比例由谁先拿到资源,CPU和内存是预先分配好的
- 上面这种按照固定比例分割就是静态分割了,仔细想想,这种做法弊端太多,假设我按照一定的比例预先分割好了,但是如果我晚上主要跑mapreduce,白天主要是HBASE工作,这种情况怎么办? 静态分割无法很好的支持,缺陷太大
- 动态隔离只要是针对YARN以及impala.所谓动态只是相对静态来说,其实也不是动态。先说YARN,在HADOOP整个环境,主要服务有哪些? mapreduce (这里再提一下,mapreduce是应用,YARN是框架,搞清楚这个概念),HBASE,HIVE,SPARK,HDFS,IMPALA,实际上主要的大概这些,很多人估计会表示不赞同,oozie,ES,storm,kylin,flink等等这些和YARN离的太远了,不依赖YARN的资源服务,而且这些服务都是单独部署就OK,关联性不大。所以主要和YARN有关也就是HIVE,SPARK,Mapreduce。这几个服务也正式目前用的最多的 (HBASE用的也很多,但是和YARN没啥关系)
-
根据上面的描述,大家应该能理解为什么所谓的动态隔离主要是针对YARN。好了,既然YARN占的比重这么多,那么如果能很好的对YARN进行资源隔离,那也是不错的。如果我有3个部分都需要使用HADOOP,那么我希望能根据不同部门设置资源的优先级别,实际上也是根据比例来设置,建立3个queue name, 开发部们30%,数据分析部分50%,运营部门20%。
-
设置了比例之后,再提交JOB的时候设置mapreduce.queue.name那么JOB就会进入指定的队列里面。默认提交JOB到YARN的时候,规则是root.users.username ,队列不存在,会自动以这种格式生成队列名称。队列设置好之后,再通过ACL来控制谁能提交或者KIll Job。
-
从上面2种资源隔离来看,没有哪一种做的很好,如果非要选一种,我会选取后者,隔离YARN资源,第一种固定分割服务的方式实在支持不了现在的业务
-
需求:现在一个集群当中,可能有多个用户都需要使用,例如开发人员需要提交任务,测试人员需要提交任务,以及其他部门工作同事也需要提交任务到集群上面去,对于我们多个用户同时提交任务,我们可以通过配置yarn的多用户资源隔离来进行实现
第一步:编辑yarn-site.xml文件
vim yarn-site.xml
<!--指定使用公平调度器,Apache默认使用容量调度器,CDH默认公平调度器-->
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
</property>
<!-- 指定我们的任务调度的配置文件路径-->
<property>
<name>yarn.scheduler.fair.allocation.file</name>
<value>/opt/module/hadoop-2.7.3/etc/hadoop/fair-scheduler.xml</value>
</property>
<!--是否启用资源抢占,如果启用,那么当整体捷群资源利用率已经超过了yarn.scheduler.fair.preemption.cluster-uti1ization-thresho1d 这么多比例的时候,允许资源抢占发生: 包括计算需要抢占的资源量,然后开始抢占-->
<property>
<name>yarn.scheduler.fair.preemption</name>
<value>true</value>
</property>
<!-- 整体集群资源利用率是否已经超过了此比例 -->
<property>
<name>yarn.scheduler.fair.preemption.cluster-utilization-threshold</name>
<value>0.8f</value>
</property>
<!-- 设置为true,且没有指定队列名,提交应用到用户名同名的队列:如果设置为false或没设置,默认提交到default队列;如果在allocation文件中指定了队列提交策略,忽略此属性 -->
<property>
<name>yarn.scheduler.fair.user-as-default-queue</name>
<value>true</value>
<description>default is True</description>
</property>
<!-- 是否允许在提交应用时,创建队列:如果设置为true,则允许,如果设置为false,如果要将应用提交的队列,没有在allocation文件中指定,那么则将应用提交到default队列;默认为true,如果队列防止策略在allocation 文件定义过,那么忽略此属性 -->
<property>
<name>yarn.scheduler.fair.allow-undeclared-pools</name>
<value>false</value>
<description>default is True</description>
</property>
第二步:添加fair-scheduler.xml文件
vim /opt/module/hadoop-2.7.3/etc/hadoop/fair-scheduler.xml
<?xml version="1.0"?>
<allocations>
<!-- 每个队列中,app的默认调度策略,默认值是fair -->
<defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>
<user name="hadoop">
<!-- 用户hadoop最多运行的app个数 -->
<maxRunningApps>30</maxRunningApps>
</user>
<!-- 如果用户没有设置最多运行的app 个数,那么userMaxAppsDefault限制用户默认运行app个数 -->
<userMaxAppsDefault>10</userMaxAppsDefault>
<!--定义我们的队列-->
<!--
weiaht队列的默认权重是1
资源池权重
aclSubmitApps
允许提交任务到此以列的用户名、所属组:
格式为:“user1,user2 group1,group2”或 group1,group2”-》如果只有组,那么组名前要加个空格
如果提交应用的用户或所属组在队列的ACLS中,或在当前队列的父队列的ACL5中,那么此用户有复限报交应用到此队列
下例:
xiaoli有权限提交应用到队列a: xiaofan在队列a的父队则dev的acls中,所以xiaofan也有权限提交应用到队列a比如有队列层级root.dev,a:
有定义
<queue name="dev">
...
<aclSubmitApps>xiaofan</aclSubmitApps>
..
<queue name="a">
..<aclSubmitApps>xiaoli</aclsubmitApps></queue>
</queue>
dclAdministerApps
允许管理任务的用户名,所属组:目前只有kill application 格式同上-->
<queue name="root">
<minResources>512 mb,4 vcores</minResources>
<maxResources>102400 mb,100 vcores</maxResources>
<maxRunningApps>100</maxRunningApps>
<weight>1.0</weight>
<schedulingMode>fair</schedulingMode>
<aclSubmitApps> </aclSubmitApps>
<aclAdministerApps> </aclAdministerApps>
<queue name="default">
<minResources>512 mb,4 vcores</minResources>
<maxResources>30720 mb,30 vcores</maxResources>
<maxRunningApps>100</maxRunningApps>
<schedulingMode>fair</schedulingMode>
<weight>1.0</weight>
<!-- 所有的任务如果不指定任务队列,都提交到default队列里面来 -->
<aclSubmitApps>*</aclSubmitApps>
</queue>
<queue name="hadoop">
<minResources>512 mb ,4 vcores</minResources>
<maxResources>20480 mb,20 vcores</maxResources>
<maxRunningApps>100</maxRunningApps>
<schedulingMode>fair</schedulingMode>
<weight>2.0</weight>
<aclSubmitApps>hadoop hadoop</aclSubmitApps>
<aclAdministerApps>hadoop hadoop</aclAdministerApps>
</queue>
<queue name="develop">
<minResources>512 mb,4 vcores</minResources>
<maxResources>20480 mb,20 vcores</maxResources>
<maxRunningApps>100</maxRunningApps>
<schedulingMode>fair</schedulingMode>
<weight>1</weight>
<aclSubmitApps>develop develop</aclSubmitApps>
<aclAdministerApps>develop develop</aclAdministerApps>
</queue>
<queue name="test1">
<minResources>512 mb,4 vcores</minResources>
<maxResources>20480 mb,20 vcores</maxResources>
<maxRunningApps>100</maxRunningApps>
<schedulingMode>fair</schedulingMode>
<weight>1.5</weight>
<aclSubmitapps>test1,hadoop,develop test1</aclSubmitapps>
<aclAdministerApps>test1 group_businessC,supergroup</aclAdministerApps>
</queue>
</queue>
<!--
包含一系列的rule元素;这些rule元素用来告诉scheduler调度器,进来的app按规则提交到哪个队列中
有多个rule的话,会从上到下进行匹配;
rule可能会带有argument;所有的rule都带create argument,表示当前rule是否能够创建一个新队列: 默认值是true
如果rule的create设置为false,且在allocation中没有配置此队列,那么尝试匹配下一个rule-->
<queuePlacementPolicy>
<!-- app被提交到指定的队列;且此xml文件没有定义此队列,create为true,刚创建;若为false,如果队列不存在,则不创建.匹配下一条rule -->
<rule name="specified" create="false"/>
<!-- aop被提交创提交此app的用户所属汕的到名命名的队别;如果队列不存在,则创,继塘匹配下一个ruTe -->
<rule name="primaryGroup" create="false" />
<!-- 如果上边rule没有匹配,则app提交到queue指定的队列,如果没有指定queue属性,其默认值root.default -->
<rule name="default" queue="root.default" />
</queuePlacementPolicy>
</allocations>
第三步:将修改后的文件分发到其他机器上
scp yarn-site.xml fair-scheduler.xml hadoop003:$PWD
scp yarn-site.xml fair-scheduler.xml hadoop002:$PWD
第四步:重启yarn集群
stop-yarn.sh
start-yarn.sh
http://hadoop001:8088/cluster/scheduler
第五步:修改任务提交的队列
- 修改代码,添加MapReduce任务需要提交到哪个队列去
Configuration configuration = new Configuration() ;
//情况1
//注释掉 configuration.set("mapreduce.job.queuename","hadoop");
//匹配规则: <rule name="primaryGroup” create="false” />
//情况2
configuration.set("mapreduce.job.queuename","hadoop") ;
//匹配规则: <rule name="specified” create="false"/>
//情况3
configuration.set("mapreduce.job.queuename","hadoopv1");
//allocation文件,注释掉<rule name="primaryGroup create="false" />;
//刷新配置 yarn rmadmin -refreshQueues
//匹配规则: <rule name="default” queue="root.default"/>
-Dmapreduce.job.queuename=dmgeo
hadoop jar /opt/install/hadoop-2.7.3/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.3-tests.jar TestDFSIO -Dmapreduce.job.queuename=test1 -write -nrFiles 10 -fileSize 128MB
- hive任务指定提交队列,hive-site.xml文件添加
<property>
<name>mapreduce.job.queuename</name>
<value>test1</value>
</property>
- spark任务指定提交的队列
1 脚本方式
--queue hadoop
2 代码方式
sparkConf.set("spark.yarn.queue","develop")