分佈式調度架構之單體調度

前言

通過前兩篇文章《分佈式體系結構之非集中式結構》和《分佈式體系結構之集中式結構》可以看出,分佈式系統架構的目的是,將多個服務器資源管理起來,尋找合適的服務器去執行用戶任務
而爲用戶任務尋找合適的服務器這個過程,在分佈式領域中叫作調度。在分佈式系統架構中,調度器就是一個非常重要的組件。它通常會提供多種調度策略,負責完成具體的調度工作。
不同的分佈式架構的調度器原理也不一樣,最常見或最直觀的是單體調度,就是任務和分佈式系統中的空閒資源直接進行匹配調度,即:調度器同時管理任務和資源。本文就詳細介紹分佈式調度架構之單體調度。

1. 什麼是單體調度

分佈式系統中的單體調度是指,一個集羣中只有一個節點運行調度進程,該節點對集羣中的其他節點具有訪問權限,可以蒐集其他節點的資源信息、節點狀態等進行統一管理,同時根據用戶下發的任務對資源的需求,在調度器中進行任務與資源匹配,然後根據匹配結果將任務指派給其他節點。
==單體調度器擁有全局資源視圖和全局任務,可以很容易地實現對任務的約束並實施全局性的調度策略。==目前很多集羣管理系統採用了單體調度設計,如Google Borg、Kubernetes 等。
如下圖所示,圖中展示了一個典型的單體調度框架:

  • Master 節點上運行了調度進程(負責資源管理、Tasks 和資源匹配);
  • Node 1,Node 2,…, Node N 爲 Slave 節點,會將 Node State 上報給 Master 節點的 Cluster State 模塊;
  • Cluster State 模塊用於管理集羣中節點的資源等狀態,並將節點的資源狀態傳送給 Scheduling Logic 模塊;
  • Scheduling Logic 模塊進行 Tasks 與資源匹配,並根據匹配結果將 Task 發送給匹配到的節點。
    在這裏插入圖片描述

2. 單體調度設計

在集羣管理中,單體調度模塊稱爲“Scheduler”或“單體調度器”。單體調度器也叫作集中式調度器,指的是使用中心化的方式去管理資源和調度任務。也就是說,調度器本身在系統中以單實例形式存在所有的資源請求和任務調度都通過這個實例進行。如下圖所示,在這一模型中,資源的使用狀態和任務的執行狀態都由調度器進行管理。
在這裏插入圖片描述
在 Borg 和 Kubernetes 這兩個集羣管理系統中,Scheduler 是它們的核心。而 Kubernetes 又是 Borg 的開源版本。所以接下來,我就以 Borg 爲例,與你講述它的調度器是如何設計的,才能保證在上萬臺機器規模的集羣上,運行來自幾千個不同應用的幾十萬個作業。

3 單體調度之Borg

3.1 作業和任務

調度的初衷是爲作業或任務尋找合適的資源,也就是說作業或任務是調度的對象。那麼作業任務到底是什麼呢?

  • 作業的屬性包括名稱、擁有者和任務個數**。
  • 作業可以有一些約束來強制其任務運行在有特定屬性的機器上,比如處理器架構、操作系統版本、是否有外網 IP 地址等;這些約束可以是硬性的也可以是柔性的,其中柔性約束表示偏好,而非需求;
  • 一個作業只在一個集羣中運行;
  • 一個任務對應的是一組 Linux 進程,運行在一臺機器上的一個容器內或直接運行在節點上;
  • 任務也有一些屬性,比如資源需求量、在作業中的序號等。

3.2 作業和任務的關係

  • 一個作業可以包含多個任務。作業類似於用戶在一次事務處理或計算過程中要求計算機所做工作的總和,而任務就是一項項具體的工作,二者屬於包含關係;
  • 一個作業中的任務大多有相同的屬性,但也可以被覆蓋 ,比如特定任務的命令行參數、各維度的資源(比如,CPU 核、內存、硬盤空間、硬盤訪問速度、TCP 端口等)。
  • 多個任務可以在多臺機器上同時執行,從而加快作業的完成速度,提高系統的並行程度。而具體將哪個任務分配給哪個機器去完成,就是調度器要做的事兒了。

3.3 Borg 系統架構

在這裏插入圖片描述
Scheduler 負責任務的調度,當用戶提交一個作業給 BorgMaster 後:

  • BorgMaster 會把該作業保存到 Paxos 倉庫中,並將這個作業的所有任務加入等待隊列中。
  • 調度器異步地掃描等待隊列,將任務分配到滿足作業約束且有足夠資源的計算節點上。
  • 調度器在掃描隊列時,按照任務的優先級從高到低進行選擇,同優先級的任務則以輪詢的方式處理,以保證用戶間的公平,並避免隊首的大型作業阻塞隊列。

注意調度是以任務爲單位的,而不是以作業爲單位

3.4 Borg 調度算法

Borg 調度算法具體包括兩個階段:

  • 可行性檢查:找到一組可以運行任務的機器(Borglet);
  • 評分:從可行的機器中選擇一個合適的機器(Borglet)。

首先,在可行性檢查階段,調度器會找到一組滿足任務約束,且有足夠可用資源的機器。比如,現在有一個任務 A 要求能部署的節點是節點 1、節點 3 和節點 5,並且任務資源需求爲 0.5 個 CPU、2MB 內存。根據任務 A 的約束條件,可以先篩選出節點 1、節點 3 和節點 5,然後根據任務 A 的資源需求,再從這 3 個節點中尋找滿足任務資源需求的節點。
注意:每個節點上的可用資源,包括已經分配給低優先級任務但可以搶佔的資源。
然後,在評分階段,調度器確定每臺可行機器的適宜性。Borg 根據某一評分機制,對可行性檢查階段中篩選出的機器進行打分,選出最適合調度的一臺機器。在評分過程中,我們可以制定多種評價指標,比如考慮如何最小化被搶佔的任務數、儘量選擇已經下載了相同 package 的機器、目標任務是否跨域部署、在目標機器上是否進行高低優先級任務的混合部署等。 根據不同的考慮因素,可以定製不同的評分算法。
其中,常見的評分算法,包括:

  • 最差匹配:該算法的核心是將任務儘量分散到不同的機器上。

比如,現在有兩個機器,機器 A 的空閒資源爲 1 個 CPU 和 1G 內存、機器 B 的空閒資源爲 0.8 個 CPU 和 1.2G 內存;同時有兩個任務,Task1 的資源需求爲 0.4 個 CPU 和 0.3G 內存、Task2 的資源需求爲 0.3CPU 和 0.5G 內存。按照最差匹配算法思想,Task1 和 Task2 會分別分配到機器 A 和機器 B 上,導致機器 A 和機器 B 都存在一些資源碎片,可能無法再運行其他 Task。

  • 最佳匹配:與“最差匹配”相反,是把機器上的任務塞得越滿越好。這樣就可以“空”出一些沒有用戶作業的機器(它們仍運行存儲服務),來直接放置大型任務。*比如,在上面的例子中,按照最佳匹配算法的思想,Task1 和 Task2 會被一起部署到機器 A 或機器 B 上,這樣未被部署的機器就可以用於執行其他大型任務了。*但是,如果用戶或 Borg 錯誤估計了資源需求,緊湊的裝箱操作會對性能造成巨大的影響。*比如,用戶估計它的任務 A 需要 0.5 個 CPU 和 1G 內存,運行該任務的服務器上由於部署了其他任務,現在還剩 0.2 個 CPU 和 1.5G 內存,但用戶的任務 A 突發峯值時(比如電商搶購),需要 1 個 CPU 和 3G 內存,很明顯,初始資源估計錯誤,此時服務器資源不滿足峯值需求,導致任務 A 不能正常運行。*所以說,最佳匹配策略不利於有突發負載的應用,而且對申請少量 CPU 的批處理作業也不友好,因爲這些作業申請少量 CPU 本來就是爲了更快速地被調度執行,並可以使用碎片資源。還有一個問題,這種策略有點類似“把所有雞蛋放到一個籃子裏面”,當這臺服務器故障後,運行在這臺服務器上的作業都會故障,對業務造成較大的影響。

因此,這兩個評分算法各有利弊。在實踐過程中,我們往往會根據實際情況來選擇更適宜的評分算法:

  • 比如,對於資源比較緊缺,且業務流量比較規律,基本不會出現突發情況的場景,可以選擇最佳匹配算法;
  • 如果資源比較豐富,且業務流量會經常出現突發情況的場景,可以選擇最差匹配算法。

Borg 的設計是支持高優先級搶佔低優先級任務的,也就是說如果評分後選中的機器上沒有足夠的資源來運行新任務,Borg 會搶佔低優先級的任務,從最低優先級逐級向上搶佔,直到可用資源足夠運行該任務。被搶佔的任務放回到調度器的等待隊列裏,而不會被遷移或使其休眠。
此外還有很多調度框架是支持用戶根據自己的場景自定義調度策略的,比如優先級策略、親和性策略、反親和性策略等。

總結

單體調度:是指一個集羣中只有一個節點運行調度進程,該調度進程負責集羣資源管理和任務調度,也就是說單體調度器擁有全局資源視圖和全局任務
單體調度的特徵,可以總結爲以下四點:

  • 單體調度器可以很容易實現對作業的約束並實施全局性的調度策略,因此適合批處理任務和吞吐量較大、運行時間較長的任務。
  • 單體調度系統的狀態同步比較容易且穩定,這是因爲資源使用和任務執行的狀態被統一管理,降低了狀態同步和併發控制的難度。
  • 調度算法只能全部內置在覈心調度器當中,因此調度框架的靈活性和策略的可擴展性不高。
  • 單體調度存在單點故障的可能性。
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章