【雲原生下離在線混部實踐系列】深刻淺出 Google Borg

Google Borg 是資源調度管理和離在線混部領域的鼻祖,同時也是 Kubernetes 的起源與參照,已成爲從業人員首要學習的典範。本文嘗試管中窺豹,簡單從《Large-scale cluster management at Google with Borg》一文中剖析 Google Borg 的設計理念和功能特色,用以拋磚引玉。html

Google Borg 是什麼?

Google Borg 是 Google 內部自研的一套資源管理系統,用於集羣資源管控、分配和調度等。在 Borg 中,資源的單位是 Job 和 Task。Job 包含一組 Task。Task 是 Borg 管理和調度的最小單元,它對應一組 Linux 進程。熟悉 Kubernetes 的讀者,能夠將 Job 和 Task 大體對應爲 Kubernetes 的 Service 和 Pod。git

在架構上,Borg 和 Kubernetes 相似,由 BorgMaster、Scheduler 和 Borglet 組成。github

Borg Allocs

Borg Alloc 表明一組可用於運行 Task 的資源,如 CPU、內存、IO 和磁盤空間。它其實是集羣對物理資源的抽象。Alloc set 相似 Job,是一堆 Alloc 的集合。當一個 Alloc set 被建立時,一個或多個 Job 就能夠運行在上面了。架構

Priority 和 Quota

每一個 Job 均可以設置 Priority。Priority 可用於標識 Job 的重要程度,並影響一些資源分配、調度和 Preemption 策略。好比在生產中,咱們會將做業分爲 Routine Job 和 Batch Job。Routine Job 爲生產級的例行做業,優先級最高,它佔用對應實際物理資源的 Alloc set。Batch Job 表明一些臨時做業,優先級最低。當資源緊張時,集羣會優先 Preempt Batch Job,將資源提供給 Routine Job 使用。這時 Preempted Batch Job 會回到調度隊列等待從新調度。異步

Quota 表明資源配額,它約束 Job 的可用資源,好比 CPU、內存或磁盤。Quota 通常在調度以前進行檢查。Job 若不知足,會當即在提交時被拒絕。生產中,咱們通常依據實際物理資源配置 Routine Job Quota。這種方式能夠確保 Routine Job 在 Quota 內必定有可用的資源。爲了充分提高集羣資源使用率,咱們會將 Batch Job Quota 設置爲無限,讓它儘可能去佔用 Routine Job 的閒置資源,從而實現超賣。這方面內容後面會在再次詳述。函數

Schedule

調度是資源管理系統的核心功能,它直接決定了系統的「好壞」。在 Borg 中,Job 被提交後,Borgmaster 會將其放入一個 Pending Queue。Scheduler 異步地掃描隊列,將 Task 調度到有充足資源的機器上。性能

一般狀況下,調度過程分爲兩個步驟:Filter 和 Score。學習

  • Filter,或是 Feasibility Checking,用於判斷機器是否知足 Task 的約束和限制,好比 Schedule Preference、Affinity 或 Resource Limit。
  • Filter 結束後,就須要 Score 符合要求的機器,或稱爲 Weight。上述兩個步驟完成後,Scheduler 就會挑選相應數量的機器調度給 Task 運行。實際上,選擇合適的調度策略尤其重要。

這裏能夠拿一個咱們生產遇到的調度問題舉例。google

生產初期,咱們的調度系統採用的 Score 策略相似 Borg E-PVM,它的做用是將 Task 儘可能均勻的調度到整個集羣上。從正面效果上講,這種策略分散了 Task 負載,並在必定程度上縮小了故障域。但從反面看,它也引起了資源碎片化的問題。因爲咱們底層環境是異構的,機器配置並不統一,而且 Task 配置和物理配置並沒有對應關係。這就形成一些配置過大的 Task 沒法運行,由此在必定程度上下降了資源的分配率和使用率。spa

爲了應付此類問題,咱們自研了新的 Score 策略,稱之爲 「Best Fillup」。它的原理是在調度 Task 時選擇可用資源最少的機器,也就是儘可能填滿。不過這種策略的缺點顯而易見:單臺機器的負載會升高,從而增長 Bursty Load 的風險;不利於 Batch Job 運行;故障域會增長。

本篇論文做者採用了一種被稱爲 hybrid 的方式,據稱比第一種策略增長 3-5% 的效率。

Utilization

資源管理系統的首要目標是提升資源使用率,Borg 亦是如此。不過因爲過多的前置條件,諸如 Job 放置約束、負載尖峯、多樣的機器配置和 Batch Job,致使不能僅選擇 「average utilization」 做爲策略指標。在Borg中,使用Cell Compaction 做爲評判基準。簡述之就是:能承載給定負載的最小 Cell。

Borg 提供了一些提升 utilization 的思路和實踐方法,有些是咱們在生產中已經採用的,有些則很是值得咱們學習和借鑑。

Cell Sharing

Borg 發現,將各類優先級的 Task,好比 prod 和 non-prod 運行在共享的 Cell 中能夠大幅度的提高資源利用率。

上面(a)圖代表,採用 Task 隔離的部署方式會增長對機器的需求。圖(b)是對額外機器需求的分佈函數。圖(a)和圖(b)都清楚的代表了將 prod Job 和 non-prod Job 分開部署會消耗更多的物理資源。Borg 的經驗是大約會新增 20-30% 左右。

箇中原理也很好理解:prod Job 一般會爲應對負載尖峯申請較大資源,實際上這部分資源在多數時間裏是閒置的。Borg 會定時回收這部分資源,並將之分配給 non-prod Job 使用。在 Kubernetes 中,對應的概念是 request limit 和 limit。咱們在生產中,通常設置 Prod Job 的 Request limit 等於 limit,這樣它就具備了最高的 Guaranteed Qos。該 QoS 使得 pod 在機器負載高時不至於被驅逐和 OOM。non-prod Job 則不設置 request limit 和 limit,這使得它具備 BestEffort 級別的 QoS。kubelet 會在資源負載高時優先驅逐此類 Pod。這樣也達到了和 Borg 相似的效果。

Large cells

Borg 經過實驗數據代表,小容量的 cell 一般比大容量的更佔用物理資源。

這點對咱們有很重要的指導意義。一般狀況下,咱們會在設計集羣時對容量問題感到猶豫不決。

顯而易見,小集羣能夠帶來更高的隔離性、更小的故障域以及潛在風險。但隨之帶來的則是管理和架構複雜度的增長,以及更多的故障點。

大集羣的優缺點正好相反。在資源利用率這個指標上,咱們憑直覺認爲是大集羣更優,但苦於無堅實的理論依據。Borg 的研究代表,大集羣有利於增長資源利用率,這點對咱們的決策頗有幫助。

Fine-grained resource requests

Borg 對資源細粒度分配的方法,目前已經是主流,在此就再也不贅述。

Resource reclamation

瞭解 Kubernetes 的讀者,應該對 resource request 和 limit,在 Google Borg 中概念相似。Job 在提交時須要指定 resource limit,它能確保內部的 Task 有足夠資源能夠運行。

有些用戶會爲 Task 申請過大的資源,以應對可能的請求或計算的突增。但實際上,部分資源在多數時間內是閒置的。與其資源浪費,不如利用起來。這須要系統有較精確的預測機制,能夠評估 Task 對實際資源的需求,並將閒置資源回收以分配給低 priority 的任務,好比 Batch Job。

上述過程在 Borg 中被稱爲 resource reclamation,對使用資源的評估則被稱爲 reservation。Borgmaster 會按期從 Borglet 收集 resource consumption,並執行 reservation。在初始階段,reservation 等於 resource limit。隨着 Task 的運行,reservation 就變爲了資源的實際使用量,外加 safety margin。

在 Borg 調度時,Scheduler 使用 resource limit 爲 prod Task 過濾和選擇主機,這個過程並不依賴 reclaimed resource。從這個角度看,並不支持對 prod Task 的資源超賣。但 non-prod Task 則不一樣,它是佔用已有 Task 的 resource reservation。因此 non-prod Task 會被調度到擁有 reclaimed resource 的機器上。

這種作法固然也是有必定風險的。若資源評估出現誤差,機器上的可用資源可能會被耗盡。在這種狀況下,Borg 會殺死或者降級 non-prod Task,prod Task 則不會受到任何影響。

上圖證明了這種策略的有效性。參照 Week 1 和 4 的 baseline,Week 2 和 3 在調整了 estimation algorithm 後,實際資源的 usage 與 reservation 的 gap 在顯著縮小。在 Borg 的一個 median cell 中,有 20% 的負載是運行在 reclaimed resource 上。

相較於 Borg,Kubernetes 雖然有 resource limit 和 capacity 的概念,但卻缺乏動態 reclaim 機制。這會使得系統對低 priority Task 的資源缺乏行之有效的評估機制,從而引起系統負載問題。這個功能對資源調度和提高資源使用率影響巨大。

Isolation

因爲 Google Borg 天生就考慮混部場景,因此資源隔離對其尤其重要。在內部場景,Google Borg 多使用 Linux 隔離,好比 chroot、cgroup 等,相似容器隔離機制。公有云側,Google Borg 則經過 VM 或沙箱技術實現 Task 間的強隔離。

在性能隔離方面,Google Borg 經過區分應用優先級的方式保證服務質量。latency-sensitive(LS) 高優任務擁有高的資源保證,Batch 低優任務佔用資源則會根據須要被抑制。

在集羣資源方面,Google Borg 將之分爲可壓縮和不可壓縮資源。與流速相關的資源,諸如 CPU、磁盤 IO 等,被定義爲可壓縮資源。這部分資源若被耗盡,Borglet 會首先降級處理低優任務,而不是直接殺死。這種作法能最大程度保證低優任務服務質量。不可壓縮資源,包括內存、磁盤空間等,在資源緊張時,任務會被按照優先級從低到高殺死,直到緊張狀況緩解。

在內核層面,Google Borg 一樣有策略保證資源隔離與複用。好比 LS 任務可獨享物理 CPU 核心,其餘 LS 任務不可複用。Batch 任務能共用這部分 CPU,經過設置低 cpus_share 的方式與 LS 任務隔離。Borget 也會週期性的調整 LS 任務,以免 Batch 任務被餓死。爲了支持高敏任務,Google Borg 對 CFS 作了加強,使之可根據 cgroup 負載預測提早搶佔 Batch 任務,從而下降 CFS 調度延遲。

總結

離在線混合部署是一套複雜的系統和技術,須要從方法論、業務、應用、資源調度系統、操做系統等多個層面的實現和配合,而且也須要長期的實戰和經驗積累。Google Borg 做爲 Google 內部的經驗結晶,系統的闡述了混部應有的基本形態,頗有啓發意義。目前咱們在騰訊內部也開發和上線了一套基於 Kubernetes 的離在線混合部署系統,支持動態資源預測、資源回收和內核級隔離。後續會持續分享混部相關的理論和實戰經驗。

參考資料

  1. Large-scale cluster management at Google with Borg:https://iwiki.oa.tencent.com/...
  2. evolution of cluster scheduler architecture:http://www.firmament.io/blog/...
  3. poseidon:https://github.com/kubernetes...
  4. design:https://docs.google.com/docum...
  5. firemament:https://github.com/camsas/fir...
【騰訊雲原生】雲說新品、雲研新術、雲遊新活、雲賞資訊,掃碼關注同名公衆號,及時獲取更多幹貨!!
相關文章
相關標籤/搜索