[譯]集羣調度架構的變革

原文地址:http://www.firmament.io/blog/scheduler-architectures.htmlhtml

集羣調度器是現代基礎設施很重要的組件,尤爲在最近幾年有很大發展。架構從單體應用的設計進化成更靈活,分散的,分佈式的設計。可是,目前不少開源能提供的仍是單體應用或缺了關鍵特性。這些特性對於真實世界的用戶很重要,由於他們須要很高的使用率。git

這是咱們發佈的第一篇關於在大集羣上進行任務調度的系列文章,那些在亞馬遜,谷歌,facebook,微軟或雅虎實際在使用的。調度是一個重要的話題,由於它直接影響操做集羣的成本:一個差調度器會致使極低的使用率,讓昂貴的機器空閒,致使浪費錢。高使用率,對於集羣本身並不容易:除非仔細的決策,負載之間會互相影響。github

架構進化

這篇文章主要討論調度架構在近些年是如何進化的,以及這爲何發生。圖一將這些不一樣的方式可視化:灰色的方塊表明一個機器,圓圈表明一個任務,一個裏面標着S的團員性表明一個調度器。箭頭表示調度器作的決策,三種顏色表明不一樣類型的負載(例如,web服務,批量分析,機器學習)。web

image.png

許多集羣調度器 - 例如高性能計算(HPC)調度器,Borg調度器,早期Hadoop調度器和Kubernetes調度器 - 都是單體的。一個單例的調度進程泡在一個機器上(例如,Hadoop初版的JobTracker,Kubernetes的kube-scheduler)而且給機器調度任務。全部的負載被同一個調度器來處理,全部的任務跑着相同的調度邏輯(圖1a)。這樣簡單並統一,卻致使了愈來愈複雜的調度器。舉個例子,能夠看看Paragon和Quasar調度器,使用了機器學習的方式來避免在資源上相互衝突的負載調度。網絡

在今天不少集羣運行不少不一樣類型的應用(在早期只有Hadoop MapReduce任務在運行)。所以維護單個的調度器實現處理混合型的負載很須要技巧,緣由以下:session

  1. 很明顯咱們指望一個調度器按不一樣的方式來處理長週期服務型任務和批量分析型任務。架構

  2. 不一樣的應用有不一樣的需求,要支持他們全部的需求須要給調度器添加許多特性,增長了邏輯和實現的複雜性。負載均衡

  3. 調度器處理任務的順序成了問題:隊列效應(隊列頭部阻塞 head-of-line blocking)與積壓問題須要當心地設計調度器。框架

綜上所述,這聽起來是一個工程上的噩夢 - 調度器的開發者會收到無窮無盡的特性需求。機器學習

二級調度架構 經過隔離資源獲取與任務來解決這個問題。這樣任務調度邏輯能夠針對特定的應用,這也能夠保持在集羣間共享的能力。Mesos的集羣管理在這方面是先驅, 同時YARN支持一部分功能。在Mesos,資源是應用級別調度器提供的(被挑選和選中),而YARN容許應用級別調度器請求資源(在返回中獲得配額)。 圖1b展現了基本思想:負責負載的調度器(S0-S2)與資源管理器進行交互,資源管理器爲集羣資源的每一個負載刻畫出動態分區。這種方式能夠支持定製化,針對負載的調度策略。

image.pngclipboard.png

如今,分離了關注點的兩級架構帶來了一些缺點:應用級調度器丟掉了一些知識,例如,他們看不到全部可能的資源點,他們基本看不到這些與資源管理器組件提供的資源獲取(Mesos)或分配(YARN)相關的選項。這有一些缺點:

  1. 優先級搶佔(高優先級任務踢掉低優先級的)的實現變得困難了:在一個基於提供的模型裏,運行任務的資源對於上一級的調度器是不可見的;在一個基於請求的模型裏,低級別的資源管理器必須理解搶佔策略(極可能與應用相關)。
  2. 調度器不能從負載運行中來考慮降級資源(例如,「吵鬧的鄰居」搶佔了IO資源),由於他們看不到他。
  3. 應用級調度關心下游資源的許多不一樣方面,但他們只有資源管理器的提供/請求接口。這個接口很容易變得很複雜。

共享狀態架構 將這個問題轉化成分佈式模型,多個集羣狀態的副本會被應用級調度器獨自更新,就像圖1c展現的。在本地更改後,調度器發起一個樂觀更新事物去更新共享的集羣狀態。這個事務可能會失敗,很明顯:一個其餘的調度器可能同一時間也在作一個衝突的變更。

image.png

最知名的使用共享狀態的設計就是Google的 Omega,和微軟的Apollo,還有Hashicorp的Nomad容器調度器。以上豆漿共享集羣狀態是如今一個單點位置:Omega的「cell state」,Apollo的「resource monitor」,Nomad的「plan queue」。Apollo與其餘兩個不一樣的是它的共享狀態是隻讀的,調度事務直接提交給集羣機器。機器本身檢查衝突並選擇接受或拒絕變更。這讓Apollo能夠在共享狀態暫時不可用時進行調度。

一個「邏輯」共享狀態設計能夠歸檔同時不須要實現整個的集羣狀態。這種方式(相似Apollo作的),每一個機器維護它們本身的狀態而且將更新發送給不一樣的agent,如調度器,機器健康監控,資源監控系統。每一個機器本身的本地狀態的視圖如今組成了一個全局共享狀態的分片。

固然,共享狀態架構也有一些缺點:他們必須與狀態信息一塊兒工做(不像中心式調度器),也會遇到高層爭搶時降級調度性能(儘管其餘架構也會遇到)。

全分佈式架構 將分化作的更完全,調度器間沒有任何協調,而且使用許多獨立的調度器來處理進入的負載,就像圖 1d裏面展現的。每一個調度器只與他們的本地數據,一般是集羣的過時數據工做。任務能夠提交給任何調度器,每一個調度器又會將任務放置在集羣的任何位置。不像兩層調度器,調度器不對隔離負責。相反,全局調度器和資源分區是在統計了多樣與隨機性的負載形成的結果後作的決策 - 相似於共享狀態調度器,只是沒有中央控制。

clipboard.png

最近的分佈式調度器運動應該是起始於Sparrow(http://dl.acm.org/citation.cfm?id=2522716)的論文,雖然底層的概念(多樣隨機性選擇)第一次出現實在1996年。Sparrow的關鍵前提是假設咱們在集羣中運行的任務會變得更短,基於一個爭論(http://dl.acm.org/citation.cfm?id=2490497),即細粒度的任務有更更多的好處。做者假設任務會變得愈來愈多,意味着調度器應該支持一種更高層的吞吐量。因爲一個單一的調度器可能沒法保持這樣的吞吐(假設每秒有100W的任務!),Sparrow將負載轉移到許多的調度器上。

這頗有意義:中央控制的缺少能夠變成一個很好的特性 ,它對一些負載適配的很好 - 在將來更多。 因爲分佈式調度器不須要互相協調,他們能夠作到比高級單體,2層,或者共享狀態調度器的邏輯更簡單。例如:
1. 分佈式調度器能夠基於一個簡單的「槽」概念,將每一個機器劃分紅n個標準的槽,對應n個並行的任務。這樣簡化了任務須要的資源不是統一的。
2. 在worker端也使用了隊列做爲簡單的服務邏輯(如,Sparrow的FIFO),保證調度有彈性,調度器能夠僅僅選擇在哪臺機器上作任務的入隊操做。
3. 分佈式調度器很難進行一個全局調度(如:公平策略或嚴格的優先級控制),由於沒有中央控制。
4. 因爲它們都被設計爲在只有不多知識時進行快速決策,分佈式調度器不能支持複雜或定製應用策略。避免干涉任務,例如,用一些後門手段。

混合架構 是最近出現的致力於經過組合單體或共享態的設計來解決全分佈架構的缺點。通常這樣作是ok的 - 好比,在Tarcilhttp://dl.acm.org/citation.cfm?id=2806779 ), Mercuryhttps://www.usenix.org/conference/atc15/technical-session/presentation/karanasos ), 和Hawkhttps://www.usenix.org/conference/atc15/technical-session/presentation/delgado ) - 有兩種調度路徑: 一個分佈式的來處理負載(如,很短的的任務,或低優先級的批處理任務), 另外一箇中心式的來處理其餘任務。圖1e展現了這種設計。每個混合調度器的行爲都與以上架構描述的部分相同。在實際的實踐中,目前據我所知尚未混合調度器在生產環境中部署。

在實踐中意味着什麼?

以上討論的不一樣的調度架構並不僅是一個學術課題,儘管他們確實在研究論文出現。做爲一個關於Borg,Mesos和Omega論文從工業界角度的擴展的討論,能夠看看Andrew Wang的精彩博文(http://umbrant.com/blog/2015/mesos_omega_borg_survey.html )。此外,不少系統的討論都部署在大型企業(微軟的Apollo,Google的Borg,Apple的Mesos)的生產環境設定,而且他們啓發了其餘可用的開源項目。

最近,許多集羣開始運行容器,因此不少關注容器的「編排框架」出現了。這些跟Google和其餘公司稱爲「集羣管理器」很像。無論怎樣,一些關於調度器討論的細節已經融入了這些框架和他們的設計規範,通常他們的關注點都是在面向用戶的調度API(由Armand Grillet報道 http://armand.gr/static/files/htise.pdf ,其對比了Docker Swarm,Mesos/Marathon, Kubernetes default scheduler)。此外,不少用戶並不知道調度器架構之間的差別,也不知道哪個架構適合他們的應用。

圖2 展現了開源編排框架的概要,他們的調度器的架構和支持的特性。在表格底部,咱們也加入了Google和微軟的閉源系統。資源粒度列指出了調度器分配任務到一個固定尺寸的slot,仍是會根據多個維度(CPU,內存,磁盤I/O貸款,網絡帶寬等)來分配資源。
image.png

一個決定合適調度架構的關鍵點就是你的集羣是否運行了混合的負載。這種case,舉例來講,就是當既有在線服務(原文:front-end services) (web負載均衡服務與memcached)和批處理數據分析(MapReduce或Spark)的狀況。爲了提升使用率這種類型頗有意義,但不一樣的應用有不一樣的調度需求。在一個混合式的設定中,單體調度器只能獲得次優解,由於單一邏輯不能以每一個應用爲基礎進行調整,雙層或共享態調度器能夠提供更好的收益。

大多數面向用戶的在線業務負載設計爲將全部資源用來服務每一個容器的峯值需求,但這樣會致使他們的使用率低於分配到的資源。這樣的狀況下,用低優先級的負載任務(保證QoS)來優化被過分訂閱的資源成爲優化有效集羣的關鍵。Mesos是目前惟一支持過分訂閱的開源系統,Kubernetes有一個提案(http://kubernetes.io/v1.1/docs/proposals/resource-qos.html )來加入這個特性。咱們指望將來這塊領域會有更多的活動,由於目前不少集羣的使用率實際上低於Google Borg集羣報道(http://dl.acm.org/citation.cfm?id=2741964 )的60-70%。咱們會繼續在從此發佈關於容量規劃,過分訂閱,高效機器使用率的內容。

最後,特定的分析和OLAP類型的應用(如,Dremel或SparkSQL查詢)能夠從全分佈式調度器受益。可是,全分佈式調度器(如Sparrow)有很嚴格的特性集限制,它在任務負載都是同一個類型時有很好的性能(如,全部的任務大約在同一個時間段運行),set-up times are low(如,任務被調度到長時間運行的worker, 像YARN中的MapReduce應用級別任務),任務會大量產生(如,許多調度判斷會在很短期產生)。咱們會在這個系列的下一個博文更細的討論下爲什麼全分佈式調度器- 混合調度器的分佈式組件只在這些應用中有意義。如今,分佈式調度器比其餘調度器更簡單,不支持多資源維度,過分訂閱,或從新調度。

大致上,圖2證實了開源框架還有一段路要走,直到它們能夠支持閉源系統的以上高級特性,這是行動的召喚:因爲缺失的特性,糟糕的使用率,不可靠的任務性能,吵雜的鄰居致使被半夜叫醒,爲一些用戶需求定製的黑科技。

不過,仍是有一些好消息:今天不少框架仍是單體調度器,他們開始向更彈性的設計變化。 Kubernetes已經開始支持插件化調度器(kube-調度器 pod能夠被另外一個API兼容的調度器pod替代),不少從V1.2後的調度器(https://github.com/kubernetes/kubernetes/blob/master/docs/proposals/multiple-schedulers.md ),開始支持自定義的策略(https://github.com/kubernetes/kubernetes/blob/master/docs/design/scheduler_extender.md )。Docker Swarm可能-按個人理解-也會增長插件化調度器的支持。

相關文章
相關標籤/搜索