閱讀755 返回首頁    go 阿裏雲 go 技術社區[雲棲]


分析資源管理係統的演變: 從Mesos,YARN再到Google Omega

背景

我覺得資源管理器所要處理的問題無外乎幾塊:資源分配的策略,資源分配的粒度,資源分配的方式,不同類型任務的調度等。看了Google新一代資源管理器Omega的論文之後,對比Mesos和YARN總結了下麵一些內容。


問題分類

任何資源調度係統都將麵臨下麵幾個問題。


該怎麼分離不同的調度工作?
     第一,可以無視任務類型,進行均衡負載地分配。第二,專門分離一些適合不同調度工作的調度器去負責各種調度反正。第三,上兩種的結合。有的係統使用多個優先級不同的任務隊列來處理任務請求(YARN就是這麼做的),看上去是分離了不同的調度工作,不過本質上不影響調度並行性,比如有多少調度器是可以同時去處理這些隊列呢?


如何選擇資源?
     資源可以全局地來自於整個集群的空閑資源,也可以限製到某個子集群。前者無疑可以達到更好的控製和優化效果,並且有些挑剔的任務可以嚐試去搶占其他任務的空閑資源。不過搶占這種方式帶來的開銷是原任務在需要這些資源的時候需要等待搶占任務對資源的釋放(YARN就是支持搶占模式的)。


如何處理資源爭搶(幹擾)?
     如果各個調度器可以自由地嚐試獲取需要的資源,那麼部分資源就會被爭搶。一種悲觀的做法是讓一個總領的調度者來分配所有所有的資源,底下的調度器隻能負責再分配拿到手裏的資源(Mesos的設計思路)。一種樂觀的做法是大家都去嚐試申請資源,當發現爭搶時一方放棄(Omega的設計思路)。後者可以大量提高並發,但是潛在問題是調度器之間的衝突可能會很頻繁。


資源分配的粒度(方式)?
     主要有兩種,all or nothing的原子性分配方式(Mesos實現)和增量分配方式(YARN實現)。前者的等待代價比較大,甚至發生某任務餓死,而且會讓比如Mapreduce這樣本身隻需要部分資源就可以先開跑的任務沒有必要地等待很久。後者則可能會有死鎖的情況發生。


不同類型

中央調度
     最原始的實現思路是一個實現了所有調度策略的單例調度者,承受所有的任務調度和資源管理(類比一代Hadoop的JobTracker)。主要問題在於難以支持豐富的策略。


靜態分離的調度
     將一個大的集群分割為幾個次集群,以應對不同的任務和調度模式。這種情況比中央式的調度要好些,但是顯然對於資源的利用率還是不夠,隻能是次優的。事實上,目前應該沒有資源管理器按照該設計思路。


雙層調度
     目前主流,對靜態分離調度的提升,讓一個總控的協調者來動態分配資源給不同的調度者,即雙層調度模式。Mesos和YARN是雙層調度的代表,介紹一下各自的情況。


     Mesos有一個中央資源分配者來動態分配資源給不同的frameworks(每個framework是一種計算框架,比如Spark、Hadoop,也可以是使用者實現的一個業務模塊)。Mesos的資源分配是Master主動向Framework提供的,Master通過將每一份空餘資源隻分給一個Framework來避免衝突,並且通過主資源公平(DRF)的方式保證所有Framework公平性和合理的資源利用率。Mesos Master的這種分配控製類似悲觀鎖,決定了其在並發上的劣勢。Framework收到Master的Offers,可以選擇拒絕部分資源(資源帶機器信息,具體為若幹CPU數和內存數),然後再分配並調起Slave上的Executor執行任務。
     Mesos比較適合短任務,並且是那種大量的執行起來比較快的任務,這些任務所需要的資源同整個集群資源相比,又是很小的這種場景。這其實又和Mesos選擇的資源分配粒度有關,Mesos的資源分配是all or nothing的類似原子性的分配方式,擁有大需求量的任務有可能會被餓死,且Mesos自身對Frameworks無優先級對待。
    所以Mesos適用的場景其實很明了,主要是由他的資源分配粒度(all or nothing)、分配策略(DRF)、分配控製(悲觀鎖)導致的。具體還可參考我前一篇文章:Mesos實戰總結


    YARN的第一層是ResourceMaster,每一個第二層的業務應用稱為ApplicationMaster,資源按Container劃分。在資源表示模型上,YARN設定的是虛擬CPU和虛擬內存。在資源管理方式上,YARN對內存資源和CPU資源采用了不同的資源隔離方案。對於內存資源,為了能夠更靈活的控製內存使用量,YARN采用了進程監控的方案控製內存使用;對於CPU資源,則采用了Cgroups進行資源隔離。此外YARN對調度語義的支持更豐富,支持:請求某個特定節點上的特定資源量;請求某個特定機架上的特定資源量;將某些節點加入或移除黑名單;請求歸還某些資源。在資源保證機製上,YARN采用的是增量資源分配機製,優先為應用程序預留一個節點上的資源,優點是不會發生餓死現象,但有一定的浪費。YARN支持資源搶占模型,負載輕的隊列會把暫時空餘的資源交給負載重的隊列使用,當輕的隊列收到應用,需要取回原先分配出去的資源的時候,就出現搶占。默認是不開啟的,可以在配置裏觸發,且搶占策略是插拔式組件。YARN Scheduler policy更豐富,包括FIFO、Capacity、Fair。


共享狀態調度
     Google Omega使用的是基於shared state的策略。每個調度器都擁有整個集群的權限,可以自由獲取資源,同時優化了並發控製來調節他們的爭搶衝突。這種方式解鎖了雙層調度器悲觀鎖導致的並發限製,讓每個Framework對全局資源可見。
     Omega采用了基於多版本的並發訪問控製方式(也稱為“樂觀鎖”, MVCC, Multi-Version Concurrency Control)。Omega對共享狀態的實現和維護方式類似多個人一起coding SVN上的一份代碼。集群維護著有一份所有資源的最小單位狀態列表(成為cell state)。每個調度器本地也有一份,調度器按照自己的策略選擇了一些需要的資源後,會進行一次原子性的commit,如果發生衝突,就像我們提SVN代碼一樣,說明該資源已經被別的Scheduler拿走, 那麼需要該調度器重新選擇,否則提交成功的話,申請就成功了。Omega的調度器執行的操作完全是並發的,且為了避免餓死,Omega支持的也是增量的分配模式(同YARN,不同於Mesos)。Omega在其他方麵的設計我就省略了,有興趣的同學可以看Omega的論文


附上Omega論文裏的一張圖,對應了以上四大問題和四大類型調度器各自的特性:


總結

其實Google的Omega的實現是很類似於雙層調度器的,隻是省略了第一層,或者說是進化掉了這第一層,把它變成了一個全局可訪問和修改的狀態維護起來,增大了並發性。實際意義上的調度器們就類似於雙層調度器裏的第二層,可以實現自己的調度策略,可以遵循自己的分配方式去執行Task。個人認為增量的分配模式的確是較好的,因為調度器拿到資源後,再分配給task的時候,還是可以實行all or nothing的,但是如果對調度器就實行all or nothing的話,那麼該調度器裏的所有任務都會因此被停滯。



全文完 :)

最後更新:2017-04-03 12:55:41

  上一篇:go c++常用函數及頭文件
  下一篇:go appsettings與connectionstrings