yarn的任務調度器
資源調度器是YARN
最核心的組件之一,是一個插拔式的服務組件,負責整個集群資源的管理和分配。YARN提供了三種可用的資源調度器:FIFO、Capacity Scheduler、Fair Scheduler。
先進先出調度器(FIFO)
FIFO
按照先到先得的原則,進行分配資源。這種調度器已經基本被淘汰了,因為比如說job1
運行完成需要24小時,job2
運行完成只需要1分鍾,但是job2
依然需要等job1
運行完成才可以開始運行,效率很低。
容量調度器(Capacity Scheduler)
apache
版本的Hadoop
默認使用容量容量調度器。容量解決了FIFO調度器效率低下的問題,但依然是要以隊列為基礎的。
因此,首先要設計容量調度器資源分配隊列,通過xml
文件配置這些信息。假如有個資源分配隊列如下:
集群60%
的資源分配給dev
隊列,集群40%
的資源分配給prod
隊列,dev
隊列的資源專門給開發組的任務分配,prod
隊列的資源專門給生產組的任務分配。
現在有個job1
要運行,把它放在spark
隊列里運行,除了spark
隊列,現在其它隊列都沒有job
要運行。在spark隊列內部使用FIFO
調度策略,還有其它job
進入spark
隊列的話,就在job1
后排隊等待。如果spark
隊列的資源足夠job1
運行 ,直接運行就行。如果spark
隊列資源不夠job1
運行,spark
會彈性占用hdp
隊列的資源,從而spark
擁有集群60%
的資源,hdp
h隊列擁有0%資源。如果60%
還是不夠,則spark
隊列會繼續擴張資源,但是不能無底洞地擴張,我們可以設置個上限,比如75%
。
擴張前:
擴展后:
公平調度器(Fair Scheduler)
cdh
版本的hadoop
默認使用公平調度器。公平調度器也是以隊列為基礎。
單個隊列里的公平:
假如說job1
一開始分配到了某個隊列里100%
的資源,如果后來job2
后來也進入該隊列,則job2
會先等待job1
一小段時間,讓job1
釋放該隊列50%
的資源給job2
。如果后來job2
運行完成了,但是job1
依舊沒運行完,則job1
又會重新占用該隊列所有的資源。示意圖如下:
隊列間的公平:
假設有AB
兩個隊列,一開始job1
進入隊列A
,隊列B
此時沒有job,
那么job1
不僅會占用隊列A
的所有資源,還有占用B
的所有資源。接着,job2
也提交上來了,job2
首先會等待小會,讓job1
釋放50%
的資源,然后再利用這些資源開始運行。后來,job3
也提交上來了,job3
也首先會等待job1
釋放50%
的資源,然后再利用這些資源開始運行。
可以看到,這個過程,job1
和job2
是平分對半資源,后來job3
進入后,job2
又和job3
平分資源。所以說,job1
被分配到的資源是最多的,緊接着是job2
和job3
。
優先級:
從上面可知,先進入隊列里先運行的job
會享受到更多的資源,那么如果一個隊列里有多個job
,誰會被優先運行?
在資源有限情況下,每個job
理想情況下獲得的計算資源與實際獲得的計算資源存在一種差距,這個差距就叫做缺額。同一個隊列里,job
的資源缺額越大,越先獲得資源優先執行,但每個job都會分配到資源,確保公平,因此可以看到多個作業同時運行。這個是Fair
模式,如果想要某個隊列使用FIFO
策略調度,可以進行設置。
hadoop默認隊列
前面我們看到了hadoop
當中有各種資源調度形式,當前hadoop
的任務提交,默認提交到default
隊列里面去了,將所有的任務都提交到default
隊列,我們在實際工作當中,可以通過划分隊列的形式,對不同的用戶,划分不同的資源,讓不同的用戶的任務,提交到不同的隊列里面去,實現資源的隔離
通過8088端口(node:8088)查看:
資源隔離
資源隔離目前有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
仍然可以執行,這個是目前無解的,默認提交JOB
到YARN
的時候,規則是root.users.username
, 隊列不存在,會自動以這種格式生成隊列名稱。 隊列設置好之后,再通過ACL
來控制誰能提交或者KIll job
。
隔離方式選擇
從上面2種資源隔離來看,沒有哪一種做的很好,如果非要選一種,我會選取后者,隔離YARN資源, 第一種固定分割服務的方式實在支持不了現在的業務。
自定義隊列
需求:現在一個集群當中,可能有多個用戶都需要使用,例如開發人員需要提交任務,測試人員需要提交任務,以及其他部門工作同事也需要提交任務到集群上面去,對於我們多個用戶同時提交任務,我們可以通過配置yarn
的多用戶資源隔離來進行實現
第一步:node01編輯yarn-site.xml
node01
修改yarn-site.xml
添加以下配置
cd /kkb/install/hadoop-2.6.0-cdh5.14.2/etc/hadoop
vim yarn-site.xml
<!-- 指定我們的任務調度使用fairScheduler的調度方式 -->
<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>/kkb/install/hadoop-2.6.0-cdh5.14.2/etc/hadoop/fair-scheduler.xml</value>
</property>
<!-- 是否啟用資源搶占,如果啟用,那么當該隊列資源使用
yarn.scheduler.fair.preemption.cluster-utilization-threshold 這么多比例的時候,就從其他空閑隊列搶占資源
-->
<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>
<!-- 默認提交到default隊列 -->
<property>
<name>yarn.scheduler.fair.user-as-default-queue</name>
<value>true</value>
<description>default is True</description>
</property>
<!-- 如果提交一個任務沒有到任何的隊列,是否允許創建一個新的隊列,設置false不允許 -->
<property>
<name>yarn.scheduler.fair.allow-undeclared-pools</name>
<value>false</value>
<description>default is True</description>
</property>
第二步:node01添加fair-scheduler.xml配置文件
node01
執行以下命令,添加faie-scheduler.xml
的配置文件
cd /kkb/install/hadoop-2.6.0-cdh5.14.2/etc/hadoop
vim fair-scheduler.xml
復制下列內容到集群配置文件的時候,特別注意有沒有全部復制了,之前就因為漏復制了一點內容,導致ResourceManager
啟動不了。
<?xml version="1.0"?>
<allocations>
<!-- users max running apps -->
<userMaxAppsDefault>30</userMaxAppsDefault>
<!-- 定義我們的隊列 -->
<queue name="root">
<minResources>512mb,4vcores</minResources>
<maxResources>102400mb,100vcores</maxResources>
<maxRunningApps>100</maxRunningApps>
<weight>1.0</weight>
<schedulingMode>fair</schedulingMode>
<aclSubmitApps> </aclSubmitApps>
<aclAdministerApps> </aclAdministerApps>
<queue name="default">
<minResources>512mb,4vcores</minResources>
<maxResources>30720mb,30vcores</maxResources>
<maxRunningApps>100</maxRunningApps>
<schedulingMode>fair</schedulingMode>
<weight>1.0</weight>
<!-- 所有的任務如果不指定任務隊列,都提交到default隊列里面來 -->
<aclSubmitApps>*</aclSubmitApps>
</queue>
<!--
weight:資源池權重
aclSubmitApps:允許提交任務的用戶名和組;
格式為: 用戶名 用戶組
當有多個用戶時候,格式為:用戶名1,用戶名2 用戶名1所屬組,用戶名2所屬組
aclAdministerApps:允許管理任務的用戶名和組;
格式同上。
-->
<queue name="hadoop">
<minResources>512mb,4vcores</minResources>
<maxResources>20480mb,20vcores</maxResources>
<maxRunningApps>100</maxRunningApps>
<schedulingMode>fair</schedulingMode>
<weight>2.0</weight>
<aclSubmitApps>hadoop hadoop</aclSubmitApps>
<aclAdministerApps>hadoop hadoop</aclAdministerApps>
</queue>
<queue name="develop">
<minResources>512mb,4vcores</minResources>
<maxResources>20480mb,20vcores</maxResources>
<maxRunningApps>100</maxRunningApps>
<schedulingMode>fair</schedulingMode>
<weight>1</weight>
<aclSubmitApps>develop develop</aclSubmitApps>
<aclAdministerApps>develop develop</aclAdministerApps>
</queue>
<queue name="test1">
<minResources>512mb,4vcores</minResources>
<maxResources>20480mb,20vcores</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>
</allocations>
第三步:將修改后的配置文件拷貝到其他機器上
將node01
修改后的yarn-site.xml
和fair-scheduler.xml
配置文件分發到其他服務器上面去
cd /kkb/install/hadoop-2.6.0-cdh5.14.2/etc/hadoop
[root@node01 hadoop]# scp yarn-site.xml fair-scheduler.xml node02:$PWD
[root@node01 hadoop]# scp yarn-site.xml fair-scheduler.xml node03:$PWD
第四步:重啟yarn集群
修改完yarn-site.xml
配置文件之后,重啟yarn
集群,node01
執行以下命令進行重啟
[root@node01 hadoop]# cd /kkb/install/hadoop-2.6.0-cdh5.14.2/
[root@node01 hadoop-2.6.0-cdh5.14.2]# sbin/stop-yarn.sh
[root@node01 hadoop-2.6.0-cdh5.14.2]# sbin/start-yarn.sh
重新登陸node01:80088,可以看到,已經新增了幾個隊列。
指定任務提交的隊列
指定mapreduce任務的提交隊列:
修改代碼,添加我們mapreduce
任務需要提交到哪一個隊列里面去
//在組裝類的run方法里添加以下內容:
Configuration configuration = new Configuration();
configuration.set("mapred.job.queue.name", "develop"); //第二個參數是要指定的隊列名稱
指定hive任務的提交隊列:
hive-site.xml
<property>
<name>mapreduce.job.queuename</name>
<value>test1</value>
</property>
指定spark任務提交的隊列
1- 腳本方式
--queue hadoop
2- 代碼方式
saprkConf.set("yarn,spark.queue", "develop")