前言
在YARN早期的隊列分配策略中,系統采用的是相對直接簡單的辦法:按照相對使用率選擇。簡單地來說,就是選擇相對使用率最低的隊列,然后把應用提交那個隊列上。但是這種簡單直接的做法,有的時候也會暴露出它的弊端。本文筆者來聊聊這個話題以及對應的一個優化分配策略。
按相對使用率分配的弊端
在舊的分配策略中,也就是按照隊列使用率來分配的策略中,會有什么弊端呢?表面上來看,這種策略十分合理啊。其實呢,這里最大的一個問題是會導致資源碎片的問題。資源碎片的產生,就不利於大任務資源塊的分配。下面通過一個例子,來具體描述一下這個問題。
假設現在我們有2個隊列Service(重要任務)隊列和Batch(短時間批任務)隊列,3個節點,每個節點內存100GB,總共100GB*3=300GB資源,Service隊列資源配比集群資源的2/3,Batch則為1/3。
假設此時兩個隊列資源使用情況已如下圖所示

然后Service隊列還有一個90G的資源請求,而Batch隊列還有一個20G的資源請求。那么問題來了,誰會有機會使用Node2資源呢?按照常理,我們想,應該是90G的資源請求,這樣使用率會更高一些。
答案其實不是這樣的,按照相對使用率算法,Service隊列使用率90/200=0.45,B則是20/100=0.2<0.45,所以系統資源優先分配給Batch隊列請求。分配后的結果圖如下(下圖Node2的20G應該顯示黃顏色的)。

其實我們可以看出,后面的90G的請求資源怎么都處理不了了,因為沒有這么大的節點空間資源了。反之,如果先分配掉90G資源,系統還是有機會處理20G資源請求的。這里就是上文提到的按照相對使用率,導致資源碎片的問題,進而導致大資源請求無法被處理。
隊列優先級分配策略
基於上面提到的問題,社區提出了隊列優先級的概念,並且可以以此作為判定條件的分配策略。當所有隊列的優先級都相等時,就等價於原來的分配算法了。相當於來說,先看優先級,優先級一致,再看相對使用率。總體來說,這樣的分配策略,會顯得更加靈活一些。
下面我們來看看隊列優先級分配策略具體是怎樣的。
首先,隊列按照樹型結構,每個隊列給它分配上優先級值,0,1,2.。。。數字越高,表明優先級越大。如下圖。

假設說,剛剛那個例子,Batch隊列對應的是D隊列,Service隊列對應的是H隊列,此時2個隊列都有等待被處理的請求,那么在使用隊列優先級的情況下,我們遵循的原則如下:
- 當2個隊列的優先級不同,這里還分為2個情況:
- 共享同一個父親節點時,2個優先級不同。
- 不屬於同個父親節點,則尋找它們的最近公共祖先,比較公共祖先下的2個孩子節點的優先級。
- 2個隊列優先級相同(祖先節點優先級都相同),等價於傳統方式的比較,根據資源相對使用率做為判定標准。
在上面的例子中,D,H隊列的比較實則是A下的節點B和C節點的比較,因為C隊列的優先級比B高,所以我們優先處理H隊列的請求。
從這里我們來仔細理解這個分配策略,它通過給隊列帶上優先級屬性,使得請求資源某種程度上具有偏向性,更重要的隊列的應用請求能夠被優先地處理。大家可以細細體會這個優先級分配策略的奧妙之處。
參考資料
[1].https://issues.apache.org/jira/browse/YARN-5864. YARN Capacity Scheduler - Queue Priorities