yarn的基本概念
yarn由兩部分組成:
- ResourceManager 負責整個叢集資源的管理和分配
- NodeManager 管理很多容器,容器中執行著正真的分散式計算程式,比如flink,或者spark。NodeManager需要向ResourceManager上報自己的任務執行情況,同時向ResourceManager發起資源申請
從客戶端向yarn提交的應用,最終都根據其資源需求,被放在NodeManager的容器中執行。yarn會對每個應用啟動一個ApplicationMaster,它負責收集和監控該應用在其它NodeManager容器中執行的分散式任務狀態,並和ResourceManager進行資源協調(具體同ResourceManager中的Scheuler)。圖中綠色的模組即為一個應用在NodeManager中的分散式執行結構。
ResourceManager由兩部分組成:
- scheduler 只負責整個叢集的磁碟、cpu、網路、記憶體等資源的管理,並根據應用的需求分配資源
- ApplicationManager 注意同應用的ApplicationMaster區分開。ApplicationManager主要負責初始化應用的ApplicationMaster容器,同時監控ApplicationMaster的執行狀態,並在其失敗後嘗試恢復。
總結來看:
yarn提供了一個分散式的資源管理和任務執行管理平臺。yarn相當於一個分散式的作業系統,管理資源和任務執行
其中的ResourceManager的ApplicationMananger負責管理應用的ApplicationMaster
ApplicationMaster又負責管理自己具體的所有分散式任務
scheduler
hadoop 2.6.0提供了兩種scheduler
- CapacityScheduler
- Fair Scheduler
兩者都是基於佇列。前者是yahoo開源貢獻的,後者是facebook開源貢獻的。重點介紹Fair Scheduler ,也是cdh官方推薦的scheduler
最新的yarn版本支援更細粒度的資源管理。加入了ReservationSystem,可以對job的資源做deadline限制,以及可預期的任務做資源保留
叢集整體的資源定義
cpu, 記憶體。配置引數
fair scheduler簡介
配置demo
<?xml version="1.0"?>
<allocations>
<queue name="sample_queue">
<minResources>10000 mb,0vcores</minResources>
<maxResources>90000 mb,0vcores</maxResources>
<maxRunningApps>50</maxRunningApps>
<maxAMShare>0.1</maxAMShare>
<weight>2.0</weight>
<schedulingPolicy>fair</schedulingPolicy>
<queue name="sample_sub_queue">
<aclSubmitApps>charlie</aclSubmitApps>
<minResources>5000 mb,0vcores</minResources>
</queue>
</queue>
<queueMaxAMShareDefault>0.5</queueMaxAMShareDefault>
<!—- Queue 'secondary_group_queueue' is a parent queue and may have
user queues under it -->
<queue name="secondary_group_queue" type="parent">
<weight>3.0</weight>
</queue>
<user name="sample_user">
<maxRunningApps>30</maxRunningApps>
</user>
<userMaxAppsDefault>5</userMaxAppsDefault>
<queuePlacementPolicy>
<rule name="specified" />
<rule name="primaryGroup" create="false" />
<rule name="nestedUserQueue">
<rule name="secondaryGroupExistingQueue" create="false" />
</rule>
<rule name="default" queue="sample_queue"/>
</queuePlacementPolicy>
</allocations>
佇列的資源限制
- 佇列可以有子佇列
- 所有佇列都是root的子佇列
基於具體資源限制
<queue name="sample_queue">
<minResources>10000 mb,0vcores</minResources>
<maxResources>90000 mb,0vcores</maxResources>
<maxRunningApps>50</maxRunningApps>
<maxAMShare>0.1</maxAMShare>
<weight>2.0</weight>
<schedulingPolicy>fair</schedulingPolicy>
</queue>
- maxRunningApps是硬性限制,即便叢集有空閒資源,也無法超越該限制。
- 叢集擴容後,也不會跟著變化,所以該種限制不推薦
基於權重資源限制
<queue name="root">
<weight>1.0</weight>
<schedulingPolicy>drf</schedulingPolicy>
<aclSubmitApps>*</aclSubmitApps>
<aclAdministerApps>*</aclAdministerApps>
<queue name="flink">
<weight>10.0</weight>
</queue>
<queue name="test1">
<weight>60.0</weight>
</queue>
<queue name="test2">
<weight>30.0</weight>
</queue>
</queue>
- 權重是基於比例劃分父佇列的所有資源
- 同級子佇列的權重相加不需要等於100, 按他們相加的整體算比例
- 隨著叢集擴容、縮容動態比例調整
佇列執行狀態限制
<maxRunningApps>10</maxRunningApps>
<maxAMShare>0.3</maxAMShare>
- maxRunningApps 佇列最大執行應用
- 佇列分配到AM的資源比例
基於使用者和分組限制
<aclSubmitApps>user1,user2,user3,... group1,group2,...</aclSubmitApps>
<aclAdministerApps>userA,userB,userC,... groupA,groupB,...</aclAdministerApps>
- aclSubmitApps 限制可以提交到佇列的使用者
- aclAdministerApps 限制可以管理該佇列的使用者,比如殺死任務
佇列的資源搶佔
搶
使用權重時,為了最大化叢集資源利用率。在叢集空閒時,繁忙的A佇列會獲得超出自己權重比例的資源,以使其快速執行。
但此時B佇列有一個任務需要執行,B佇列的資源被A佇列佔用,B佇列只有等待A佇列中的任務執行完成釋放屬於自己的資源
但如果A佇列一直有任務執行,B佇列就要一直等下去,為了避免這種情況發生,需要引入搶佔機制
在B佇列中配置自己能忍耐的極限,超過則要求fair scheduler幫忙搶資源,殺死A佇列中的任務,釋放資源
首先在yarn-site.xml中啟用搶佔功能
<property>
<name>yarn.scheduler.fair.preemption</name>
<value>true</value>
</property>
然後在fair-scheduler.xml 對應的佇列中配置
<queue name="B">
<weight>10.0</weight>
<fairSharePreemptionTimeout>60</fairSharePreemptionTimeout>
<fairSharePreemptionThreshold>0.5</fairSharePreemptionThreshold>
</queue>
- fairSharePreemptionThreshold (0到1的小數)當佇列獲得的資源小於 fairSharePreemptionThreshold乘以自己應獲得的資源時,
- fairSharePreemptionTimeout 並且等待了60s,都還沒獲取自己要求的這個資源。那fair scheduler將會幫忙殺死A佇列中的任務,分配資源給B佇列
被搶
那如果A佇列本身的任務非常重要,不允許執行過程中被殺,那麼需要以下配置
<queue name="B">
<weight>10.0</weight>
<allowPreemptionFrom>false</allowPreemptionFrom>
</queue>
- allowPreemptionFrom 是否允許排程器從自己這搶走資源,預設為true
佇列內部資源排程策略
前面說了佇列之間通過權重、或具體大小來劃分叢集資源。但佇列內部對於先後提交的多個任務有以下幾種排程方式
- fair FairSharePolicy
- fifo FifoPolicy
- drf DominantResourceFairnessPolicy
FairSharePolicy
基於記憶體做公平排程。而不不同應用對cpu的的需求
FifoPolicy
先進先出,優先保證先提交到佇列的應用所需要的所有資源,有空閒再給後續任務
DominantResourceFairnessPolicy
基於應用申請記憶體和cpu所在總資源的比例大小來選取佔絕對主導權的(dominant)比例
假設總的佇列資源是100 CPUs, 10000 GB Memory
A應用程式需求的資源是:2 CPUs, 300 GB Memory,其申請各項的佔比為 2% of CPUs vs 3% of Memory
B應用程式需求的資源是:6 CPUs, 100 GB Memory ,其申請的各項佔比為 6% of CPUs vs 1% of Memory
所以A佔主導的記憶體申請,%3
B的佔主導的應該是cpu申請,%6
B的主導比例是A的兩倍,所以B會獲得多餘A兩倍的資源
對應論文:https://people.eecs.berkeley.edu/~alig/papers/drf.pdf
佇列的分配規則
<queuePlacementPolicy>
<Rule #1>
<Rule #2>
<Rule #3>
.
.
</queuePlacementPolicy>
- 流程方式順序選擇規則,不匹配這下一條
規則的種類有
<rule name=”specified” create=”false”>
<rule name="user"/>
<rule name="primaryGroup"/>
<rule name="secondaryGroupExistingQueue"/>
<rule name="nestedUserQueue" create=”true”>
<!-- Put one of the other Queue Placement Policies here. -->
</rule>
<rule name="default" queue="default" />
<rule name="reject"/>
specified rule
user rule
primary rule
secondaryGroupExistingQueue
nestedUserQueue
<rule name="nestedUserQueue" >
<rule name="primaryGroup" create="true" />
</rule>
default 和 reject
兜底,以上所有規則不滿足,default為使用預設規則,reject為直接拒絕掉
通過cdh的一個叢集資源劃分示例
- azkaban離線計算,60%, 可搶佔,不可被搶佔
- flink實時計算,10%, 可搶佔,不可被搶佔
- hueuser 即系查詢,30%,可搶佔,不可被搶佔
對應xml配置
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<allocations>
<queue name="root">
<weight>1.0</weight>
<schedulingPolicy>drf</schedulingPolicy>
<aclSubmitApps>*</aclSubmitApps>
<aclAdministerApps>*</aclAdministerApps>
<queue name="default">
<weight>1.0</weight>
<schedulingPolicy>drf</schedulingPolicy>
</queue>
<queue name="flink">
<weight>10.0</weight>
<fairSharePreemptionTimeout>60</fairSharePreemptionTimeout>
<fairSharePreemptionThreshold>0.5</fairSharePreemptionThreshold>
<allowPreemptionFrom>false</allowPreemptionFrom>
<schedulingPolicy>drf</schedulingPolicy>
</queue>
<queue name="azkaban" type="parent">
<weight>60.0</weight>
<fairSharePreemptionTimeout>60</fairSharePreemptionTimeout>
<fairSharePreemptionThreshold>0.5</fairSharePreemptionThreshold>
<allowPreemptionFrom>false</allowPreemptionFrom>
<schedulingPolicy>drf</schedulingPolicy>
</queue>
<queue name="hueuser" type="parent">
<weight>30.0</weight>
<fairSharePreemptionTimeout>60</fairSharePreemptionTimeout>
<fairSharePreemptionThreshold>0.5</fairSharePreemptionThreshold>
<schedulingPolicy>drf</schedulingPolicy>
</queue>
</queue>
<defaultQueueSchedulingPolicy>drf</defaultQueueSchedulingPolicy>
<queuePlacementPolicy>
<rule name="specified" create="true"/>
<rule name="nestedUserQueue">
<rule name="primaryGroup" create="true"/>
</rule>
<rule name="default"/>
</queuePlacementPolicy>
</allocations>
基於組限制hue使用者
使用者組的方式進行佇列分配時,yarn的實現是在linux賬號體系下去拿該使用者對應的組。而預設你在hue中新建的賬號在hive的linux機器上沒有對應的使用者,所以上述配置在分組時,會異常,從而導致使用者無法在hue中做hive查詢。
所以後面新增新的hue使用者的流程是
- 在hue中新建一個使用者假設名為tom
- 去hiveserver 所在機器上新建同名使用者
adduser tom
- 由於linux中新建使用者的預設primary group跟使用者名稱同名,這裡需要將其修改為hueser 組(該組我已在107上建立),所以需要接著執行命令
usermod -g hueuser tom