歡迎光臨
每天分享高質量文章

集群調度系統的演進

 

Kubernetes 已經成為容器編排領域的事實標準,將來所有應用都會在 Kubernetes 上開發和運行,這個系列文章的目的是深入淺出的介紹 Kubernetes 底層實現的原理。
Kubernetes 是一個集群調度系統,今天這篇文章主要是介紹 Kubernetes 之前一些集群調度系統的架構,通過梳理他們的設計思路和架構特點,我們能夠學習到集群調度系統的架構的演進過程,以及在架構設計時需要考慮的主要問題,對理解 Kubernetes 的架構會非常有幫助。

 

基本概念

 

我們需要先瞭解集群調度系統裡面的一些基本的概念,為了方便大家理解,我通過一個例子來解釋這些概念,假設我們要實現一個分佈式的定時任務系統(分佈式的 Cron),這個系統管理了一組 Linux 主機,用戶通過系統提供的的 API / UI 定義定時任務(就類似在 Linux 裡面定義 Crontab) ,系統會根據任務的定義,來定時來執行相應的任務,在這個例子裡面有如下基本概念:
  • 集群(Cluster):這個系統管理的 Linux 主機組成一個資源池,用來運行任務,這個資源池就是集群。

  • 作業(Job):就是定義集群如何去執行任務,在例子裡面 Crontab 就是一個簡單的作業,裡面明確的告訴了集群需要在什麼時間(時間間隔) ,做什麼事情(執行的腳本)。一些作業的定義會複雜很多,比如還會定義一個作業分幾個任務做完,以及任務之間的依賴關係,還包括每一個任務對資源的需求。

  • 任務(Task):作業需要被調度成具體的執行任務,如果我們定義了一個作業是每天晚上凌晨 1 點執行一個腳本,那麼在每天凌晨 1點被執行的這個腳本行程就是任務。

在設計集群調度系統的時候,這個調度系統的核心任務也就是 2 個:
  • 任務調度。作業提交給集群調度系統之後,需要對提交的作業拆分成具體的執行任務,並且跟蹤和監控任務的執行結果。在分佈式 Cron 的例子中,調度系統需要按照作業的要求定時啟動行程,如果行程執行失敗,需要重試等,一些複雜的場景,比如 Hadoop 的 Map Reduce ,調度系統需要把 Map Reduce 任務拆分成相應的多個 Map 和 Reduce 任務,並且最終拿到任務執行結果的資料。

  • 資源調度:本質上是對任務和資源做匹配,根據集群中主機的資源使用情況,分配合適的資源來運行任務。和操作系統的行程調度演算法比較類似,資源調度的主要標的是,在固定的資源供給的情況下,盡可能提高資源使用率,減少任務等待的時間(任務等待資源去執行的時間),減少任務運行的延遲或者響應時間(如果是批量任務的話,就是任務從開始執行到結束的時間,如果在線響應式任務的話,比如 Web 應用,就是每一次響應請求的時間),盡可能公平(資源公平的被分配到所有任務)的同時,還需要考慮任務的優先級。這些標的裡面有一些是有衝突的,需要平衡,比如資源利用率和響應時間,公平和優先級。

 

Hadoop MRv1

 

Map Reduce 是一種並行計算模型,Hadoop 是可以運行這種並行計算的集群管理平臺,其中 MRv1 是 Hadoop 平臺的 Map Reduce 任務調度引擎的第一代版本,簡單來說,用戶定義了 一個 Map Reduce 計算,提交給 Hadoop 之後,由 MRv1 負責在集群上調度和執行這個作業,並且傳回計算結果。MRv1 的架構看起來是這樣的:

架構還是比較簡單的,標準的 Master/Slave 的架構,有 2 個核心組件:
  • Job Tracker 是集群主要的管理組件,同時承擔了資源調度和任務調度的責任。

  • Task Tracker 運行在集群的每一臺機器上,負責在主機上運行具體的任務,並且彙報狀態。

隨著 Hadoop 的流行和各種需求的增加,MRv1 有如下問題需要改進:
  1. 性能有一定瓶頸:支持管理的最大節點數是 5千個節點,支持運行的任務最大數量 4萬,還有一定的提高空間。

  2. 不夠靈活,無法擴展支持其他任務型別。Hadoop 生態裡面除了 Map Reduce 型別任務,還有其他很多任務型別需要調度,比如 Spark,Hive,HBase,Storm,Oozie 等,所以需要一個更加通用的調度系統,能夠支持和擴展更多的任務型別。

  3. 資源利用率比較低。MRv1 給每個節點靜態配置了固定數目的 Slot ,每個 Slot 也只能夠運行的特定的任務的型別(Map or Reduce),這就導致資源利用率的問題,比如大量 Map 任務在排隊等待空閑資源,但實際上機器有大量 Reduce 的 Slot 被閑置。

  4. 多租戶和多版本的問題。比如不同部門在同一個集群裡面運行任務,但是彼此是邏輯上隔離的,或者在同一個集群裡面運行不同版本的 Hadoop。

 

YARN

 

YARN(Yet Another Resource Negotiator)是 Hadoop 的第二代調度系統,主要目的就是為瞭解決 MRv1 中的各種問題。YARN 的架構看起來是這樣的:

YARN 簡單的理解就是,相對於 MRv1 的主要改進就是,把原來的 JobTrack 的職責,拆分給兩個不同的組件來完成:Resource Manager 和 Application Master:
  • Resource Manager:承擔資源調度的職責,管理所有資源,將資源分配給不同型別的任務,並且通過“可插拔”的架構來很容易的擴展資源調度演算法。

  • Application Master:承擔任務調度的職責,每一個作業(在 YARN 裡面叫做 Application)都會啟動一個對應的 Application Master,它來負責把作業拆分成具體的任務、向 Resource Manager 申請資源、啟動任務、跟蹤任務的狀態並且彙報結果。

我們看看這種架構改變是如何解決 MRv1 的各種問題的:
  • 將原來的 Job Tracker 的任務調度職責拆分出來,大幅度提高了性能。原來的 Job Tracker 的任務調度的職責拆分出來由 Application Master 承擔,並且 Application Master 是分佈式的,每一個實體只處理一個作業的請求,將原來能夠支撐的集群節點最大數量,從原來的5千節點提升到1萬節點。

  • 任務調度的組件,Application Master,和資源調度解耦,而且是根據作業的請求而動態創建的,一個 Application Master 實體只負責一個作業的調度,也就更加容易支持不同型別的作業。

  • 引入了容器隔離技術,每一個任務都是在一個隔離的容器裡面運行,根據任務對資源的需求來動態分配資源,大幅提高了資源利用率。不過有一個缺點是,YARN 的資源管理和分配,只有記憶體一個維度。

 

Mesos 的架構

 

YARN 的設計標的依然是服務於 Hadoop 生態的調度,Mesos 的標的更近一步,被設計成一個通用的調度系統,能夠管理整個資料中心的作業,看的出來 Mesos 的架構設計很多借鑒了 YARN,將作業調度和資源調度分別由不同的模塊承擔,不過 Mesos 和 YARN 很大不同的地方是對資源的調度方式,設計了一個叫非常獨特的 Resource Offer 的機制,進一步釋放了資源調度的壓力,增加了作業調度的擴展性。

Mesos 的主要組件是:
  • Mesos Master ,單純是承擔資源分配和管理的組件,的對應到 YARN 裡面就是那個 Resource Manager,不過工作方式會稍微有些不太一樣,後面會講到。

  • Framework,承擔作業調度,不同的作業型別都會有一個對應的 Framework,比如負責 Spark 作業的 Spark Framework。

Mesos 的 Resource Offer
看起來 Mesos 和 YARN 架構非常類似,不過實際上在資源管理的方面, Mesos 的 Master 有非常獨特(甚至有些奇怪)的 Resource Offer 機制:
  • YARN 中 Resource Manager 提供資源的方式是被動的,當資源的消費者(Application Master) 需要資源的時候,會呼叫 Resource Manager 的接口來獲取到資源,Resource Manager 只是被動的響應 Application Master 的需求。

  • Mesos 的 Master 提供資源的方式是主動的。Mesos 中的 Master 會定期的主動推送當前的所有可用的資源(就是所謂的 Resource Offer,後面統一都叫 Offer)給 Framework,Framework 如果有任務需要被執行,不能主動申請資源,只有當接收到 Offer 的時候,從 Offer 裡面挑選滿足要求的資源來接受(在 Mesos 裡面這個動作叫做 Accept),剩餘的 Offer 就都拒絕掉(這個動作叫做 Reject),如果這一輪 Offer 裡面沒有足夠能夠滿足要求的資源,只能等待下一輪 Master 提供 Offer。

相信大家看到這個主動的 Offer 機制的時候,會和我有同樣的感覺,就是效率比較低,會產生如下問題:
  • 任何一個 Framework 的決策效率會影響整體的效率。為了一致性,Master 一次只能給一個 Framework 提供 Offer,等待這個 Framework 挑選完 Offer 之後,再把剩餘的提供給下一個 Framework,這樣的話,任何一個 Framework 做決策的效率就會影響整體的效率;

  • “浪費”很多時間在不需要資源的 Framework 上。Mesos 並不知道哪個 Framework 需要資源,所以會出現有資源需求的 Framework 在排隊等待 Offer,但是沒有資源需求的 Framework 卻頻繁收到 Offer 的情況。

針對上面的問題,Mesos 提供了一些機制來做一定程度的緩解,比如給 Framework 設置一個做決策的超時時間,或者允許 Framework 可以通過設置成 Suppress 狀態來表示不需要接受 Offer等,因為不是本次討論的重點,所以細節就不展開了。
實際上,Mesos 採用這種主動 Offer 的機制,也是有一些明顯的優點的:
  • 性能明顯提高。根據模擬測試一個集群最大可以支撐 10 萬個節點,Twitter 的生產環境最大集群支撐 8 萬個節點,主要原因是 Mesos Master主動 Offer 的機制,進一步簡化了 Mesos Master 的工作職責,Mesos 中將資源調度的過程(資源 —> 任務的匹配)分成了 2 個階段:資源 —> Offer —> 任務 。Mesos Master 只負責完成第一個階段,第二個階段的匹配交給 Framework 來完成。

  • 更加靈活,能夠滿足更加負責的任務調度的策略。舉個例子,All Or Nothings 的資源使用策略。

Mesos 的調度演算法 DRF(Dominant Resource Fairness)
關於 DRF 演算法,其實對我們理解 Mesos 架構並沒有什麼關係,但是在 Mesos 中卻非常核心和重要,所以多啰嗦幾句。
上面說了,Mesos 是輪流給 Framework 提供 Offer 的,那麼每次該挑選哪個 Framework 提供 Offer 呢?這就是 DRF 演算法要解決核心的問題, 基本原則就是要兼顧公平和效率,在經量滿足所有 Framework 對資源需求的同時,也要應該盡可能公平,避免某一個 Framework 占用太多資源而把其他 Framework 給“餓死”。
DRF 是 min-max fairness 演算法的一個變形,簡單來說就是每次都挑選支配資源占用率(Dominant Resource Usage)最低的那個 Framework 提供 Offer。如何計算 Framework 的“支配資源占用率”呢?就是從 Framework 占用的所有資源型別裡面,挑選資源占用率最小的那個資源型別最為支配資源(Dominant Resource),它的資源占用率就是這個 Framework 的支配資源占用率( Dominant Resource Usage),舉個例子,一個 Framework X 的 CPU 占用了整體資源的 20%,記憶體是 30%,磁盤是 10%,那麼這個 Framework 的支配資源占用率就是 10%,官方術語把磁盤叫做支配資源, 這個 10% 叫做支配資源占用率。
DRF 的最終目的是把資源平均的分配給所有 Framework,如果一個 Framework X 在這一輪 Offer 中接受(Accept Offer)了過多的資源,那麼就要等更長的時間才能獲得下一輪 Offer 的機會。不過仔細的讀者會發現,這個演算法裡面有一個假設,就是 Framework 接受了資源之後,會很快釋放掉,否則就會有 2 個後果:
  1. 其他 Framework 被“餓死“。某個 Framework A 一次性的接受了集群中大部分資源,並且任務一直運行不退出,這樣大部分資源就被 Framework A 一直霸占了,其他 Framework 就沒法獲得資源了。

  2. 自己被餓死。因為這個 Framework 的支配資源占用率一直很高,所以長期無法獲得 Offer 的機會,也就沒法運行更多的任務。

所以實際上,Mesos 只適合調度短任務,Mesos 在設計之初就是為資料中心中的段任務而設計的。

 

總結一下

 

從大的架構上,所有調度系統的架構都是 Master / Slave 的架構,Slave 端安裝在每一臺需要管理的機器上,用來收集主機信息,在主機上執行任務。Master 主要負責做資源調度和任務調度,資源調度對性能要求比較高,任務調度對可擴展性要求較高,總體趨勢是講這兩類職責解耦,分別由不同的組件來完成。

已同步到看一看
赞(0)

分享創造快樂