本節分爲三部分:
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調優配置詳解
http://blog.itpub.net/30089851/viewspace-2127851/
⑧面試題:
https://blog.csdn.net/qq_24073707/article/details/80476480
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調度器即得到了高的資源利用率又能保證小任務及時完成。
調度器參考:http://www.cnblogs.com/gxc2015/p/5267957.html
’
調度器具體怎麼配置,不用關心,擴展知識。生產上是用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>