Google大規模集羣管理系統Borg的解讀

0 背景html

        0.1 Borg簡介程序員

        Borg是Google內部的大規模集羣管理系統,已經延續十餘年的時間,大致上與MapReduce、GFS、BigTable、Chubby是同時代的產物,但一直被雪藏,直至今年才發表論文,披露其實現細節。論文連接(http://research.google.com/pubs/pub43438.html)。web

        Kubernetes被認爲是Borg的開源版本(研發團隊部分重合、功能簡化聚焦、架構相似)。許多研發Borg的工程師如今正投身於Kubernetes系統,並從Borg中汲取經驗,不斷打磨Kubernetes。這也是我將此篇博客歸類到「Docker& k8s」的緣由。算法

       0.2 筆者與Borgdocker

       筆者所在團隊的前輩曾經聯合騰訊公司研發過集羣管理系統T-Borg(公司內部代號),即Torca的原型。從名字上看,不難推測T-Borg也是相似Borg的集羣管理系統。筆者本人從碩士階段就一直從事雲平臺/集羣管理系統的研發,期間也曾從T-Borg中汲取經驗。能夠說我一直在關注和學習Borg系統,所以Borg公開發表論文,我也在第一時間關注。緩存

 

1 Abstract & Introduction安全

       Borg系統爲Google進行集羣管理,其上運行着十萬級別的做業(Job)、數千級別的應用(App)、管理着數萬級別的機器(Machine)。服務器

       Borg的三大優點:網絡

     (1)隱藏資源管理和錯誤處理的細節,使得用戶能夠聚焦應用開發;架構

     (2)高可靠性和高可用性,同時支持應用的高可靠和高可用;

     (3)在數萬節點上有效運行工做負載。

       我的解讀:這三條優點說的已經比較明確了,若是再總結一下,能夠歸結爲(1)易用性(解決分佈式共性問題,屏蔽細節);(2)高可用性;(3)可擴展性(數萬節點)和高利用率(有效運行)。這些都是雲平臺須要解決的核心問題。

       Borg不是第一個關注這些問題的系統,倒是僅有的幾個如此大規模的系統之一。我的解讀:這句話說得較爲低調,Borg有多是這個世界上規模最大的集羣管理系統。

 

2 用戶視角 The user perspective

       Borg的用戶是Google的開發人員和系統管理員。用戶以做業(Job)的形式向Borg提交工做,其中每一個做業(Job)包含着一個或者多個運行相同程序的任務(task)。每一個做業(Job)運行在同一個Borg單元(Cell)中,單元(Cell)是一組機器的集合。

       2.1 工做負載

       Borg Cell中運行着異構的工做負載,主要包括兩個部分:服務和批處理做業。服務長時間運行,幾乎不會中止,處理短時間的、延遲敏感的請求,服務一般是面向終端用戶的產品(如Gmail、Google Docs、web search)和一些內部基礎設施服務(BigTable,即HBase的Google版本)。批處理做業運行時間在幾秒到幾天不等;它們對短時間性能波動並不敏感。工做負載會在Cell上混合部署。

       大部分應用框架已經運行在Borg上多年,包括內部的MapReduce、FlumeJava、Millwhell、Pregel。Google的分佈式存儲系統也都運行在Borg之上,包括GFS、BigTable、Megastore等。

       論文將高優先級的做業成爲「生產型做業」(prod),將其餘稱爲「非生產型做業」(non-prod)。大部分長時間運行的服務都是生產型做業,生產型做業被分配了大約70%的CPU資源並佔用了大約60%的利用率;同時被分配了大約55%的內存資源並佔用了大約85%的內存利用率。

       我的解讀:能夠發現,在Google內部,不管是服務型仍是批處理型,絕大多數做業都運行在Borg之上,包括其核心產品和很是重要的基礎設施。

       2.2 集羣和單元Cluster and cells

       一個集羣Cluster一般包括一個大規模的單元Cell和若干個小規模的用於測試和特殊目的的單元Cell。Cell的規模大約是10k節點,且機器是異構的。

       我的解讀:集羣Cluster包含若干個單元Cell,單元Cell又包含大量的機器Machine。三者關係示意圖以下圖所示。相比於Cluster和Machine,Cell的概念較爲少見。但其實Cell的概念在工程實踐中比較常見,不少項目在上線之初將Cluster做爲一個總體使用,後來出於某種目的(絕大多數時候是就是爲了測試)又將集羣分爲兩部分使用,這樣集羣就被劃分紅爲一個主體Cell和一個用於測試的小Cell,與論文描述一致。能夠說,Cell的概念脫胎於實踐,而不是Google拍腦殼想出來的。

wKiom1Ym7N3DkPdpAAGhC9Q7NIA298.jpg

       2.3 做業和任務Jobs and tasks

       一個Borg做業Job具備屬性,包括name、owner、task數量等。Job具備約束(constraint)來強制其任務運行在具備特定屬性的機器上,例如處理器架構、OS版本、IP地址等。約束能夠分爲硬約束和軟約束,前者是需求,必須知足;後者是偏好,儘可能知足。

       我的解讀:文中提到了約束constraint的概念,在集羣調度領域提出約束主要是爲了解決任務和集羣的異構性挑戰。本人在研究和實踐中也一直關注約束,並在工程中應用了本身的相關研究成果。這裏不作過多展開,若是要進一步瞭解約束的概念以及軟硬約束的區別,能夠研讀下面兩篇論文:Modelingand Synthesizing Task Placement Constraints in Google Compute Cluster(http://research.google.com/pubs/pub36953.html)和Alsched: Algebraic Scheduling of Mixed Workloads in Heterogeneous Clouds(http://www.pdlNaNu.edu/PDL-FTP/CloudComputing/alsched-socc2012.pdf)。

       每一個任務,能夠映射爲一個container中的一組Linux程序。Borg絕大部分工做負載不運行在虛擬機中,這主要是因爲虛擬機性能開銷較大,此外一些硬件不支持虛擬化。

一個任務也具備屬性,例如資源需求和task index。Borg程序採用靜態連接庫,以減小對運行環境的依賴,軟件包中主要包括二進制程序和數據文件。

       我的解讀:在雲平臺工程實踐中,打包和部署是一個難以忽視的重要挑戰。Docker基本上就是憑藉解決部署問題而風靡開源界的。在Docker出現以前,傳統虛擬機(例如KVM、Xen)雖然支持鏡像部署,可是性能開銷較大;輕量級虛擬化(例如LXC和更底層的cgroups)雖然性能開銷小,可是自身不具有鏡像,打包部署瑣碎繁雜。Docker兼具兩者優點,解決了這個問題。

       用戶向Borg發送RPC用以操做做業。用戶能夠提交做業、查詢做業,也能夠改變做業、任務屬性。做業Job和任務task的狀態圖以下圖所示。用戶能夠觸發submit、kill和update事務。

wKiom1Ym7QjDcRz0AADNbwKJWfY464.jpg

       我的解讀:做業Job和任務task的生命週期管理要基於這個狀態圖來實現,特別是錯誤處理,要在狀態圖的基礎上基於事件觸發來實現。例如,在我實現的系統中,當任務finish、fail、kill、lost時,系統會根據特定事件進行專門處理。

       任務Task在被搶佔以前,會收到通知,兩者都是經過Unix信號,搶佔經過SIGKILL信號,程序直接退出;通知經過SIGTERM信號,能夠被處理。這樣作主要是爲了讓程序關閉前清理環境、保存狀態、完成當前請求等。

       我的解讀:雲平臺須要支持任務「優雅」的退出,Borg不是個例,LXC和Docker也有相似功能。例如,docker stop命令就是優雅退出,其機制與Borg相似;而docker kill則是直接退出。

       2.4 Allocs

       一個Borg alloc是一臺machine上預留資源的集合,能夠用於一個或多個任務運行。Alloc被用於爲將來的task預留資源,用來在中止和再次啓動任務之間保持資源,或者將不一樣做業Job的任務task聚合在一塊兒運行(例如一個web服務器實例和一個相關的logsaver)。

       一個Alloc集合相似一個job:它是在多個機器上預留資源的一組alloc。一旦一個alloc集合被建立,一個或者多個做業Job就能夠被提交在其中運行。簡而言之,一個task與一個alloc對應,一個job與一個alloc集合對應。

       我的解讀:Alloc是allocation的簡稱,應該能夠理解爲資源分配對應的邏輯單元,或者直接理解爲資源單元。初讀以爲alloc相似container,可是因爲一個alloc能夠支持一個或多個task運行,所以alloc實際上更相似Kubernetes中的pod(一個pod中包含若干個container)。另外,Kubernetes中沒有Job和Task的概念,我我的感受Kubernetes中的Service相似於Borg中Job(僅限於服務型Job)的概念,Kubernetes中container相似於Borg中task的概念。固然,僅是相似,說徹底相同是不許確的。

       2.5 優先級,配額和准入控制 Priority, quota, and admission control

       每一個做業都有一個優先級,具體形式是一個小的正整數。Borg定義非重疊優先級,包括:monitoring, production, batch, and best effort (also known as testing or free),生產型做業(prod job)包含前兩種優先級。

       爲了不「搶佔洪流」,Borg不容許一個生產型做業區搶佔另外一個,只容許生產型做業搶佔非生產型做業。

       資源配額Quota是一組資源量化表達式(CPU、RAM、Disk等),它與一個優先級和一個時間段對應。若是Quota不足,做業提交會被拒絕。

       我的解讀:在咱們的工程實踐中,Quota設置沒有如此細粒度,可是基本思路一致。有一點不一樣須要說明一下,在Borg中若是Quota不足會當即拒絕做業提交;可是在咱們的系統中,Quota不足並不影響做業提交,做業會進入等待隊列,待前序做業運行完畢、Quota充足後,系統再自動調度和運行該做業。起初,我對於Borg的設計不是很理解,拒絕提交不是更「麻煩」嗎?後來我思考,個人系統的用戶可能是不太熟悉分佈式的應用開發人員,但願咱們儘量的爲他們屏蔽細節,因此咱們自動化的進行提交、調度和運行;Borg的用戶是Google開發人員,是高水平的程序員,我猜想他們須要瞭解一些必要的「細節」來進行後續操做。前者更須要便利,後者更須要靈活,用戶的不一樣致使系統設計機制的不一樣。

       2.6 名字服務和監控 Naming and monitoring

       僅僅是建立和放置任務是不夠的,一個服務的客戶端或者其餘系統須要找到服務,當服務被從新定位到新機器以後也是如此。爲此,Borg建立了一個穩定的Borg名字服務(BNS),用於爲每一個任務命名。任務名字包括cell name、job name和task number這個三元組。Borg將任務的主機名和端口號寫入Chubby中的一致性、高可用文件。Borg也會將做業規模和任務健康信息寫入Chubby,負載均衡器LoadBalancer據此來進行路由。

       我的解讀:名字服務也被稱爲服務發現,一般使用高可用存儲系統(例如Chubby,能夠視爲Google內部的Zookeeper,固然如今開源界etcd彷佛更火)存儲任務名字與訪問方式endpoint的映射關係。在Borg中,任務名字包括cell name、job name和task number三元組;訪問方式endpoint則是hostname和port二元組。客戶端或其餘系統須要訪問服務時,就訪問BNS根據任務名字查詢訪問方式endpoint,以此來「發現」服務。

       每一個任務會構建HTTP server來發布其健康信息和性能指標,Borg根據URL來監控任務,並重啓異常任務。

       我的解讀:在咱們的工程實踐中,每一個任務(更準確說實際上是虛擬機)中都會包含一個代理agent,這個代理開機自啓,定時上傳心跳,內含健康信息和性能指標。能夠說上傳內容是相似的,可是通訊方式是不一樣的。咱們是虛擬機代理定時主動上傳心跳,不過最近感受「發佈信息,由須要該信息的組件來查詢」這種服務化的通訊方式更爲優雅和主流。

 

3 Borg架構 Borg architecture

       一個Borg cell包含一組機器集合、一個邏輯中央控制器Borgmaster、每臺機器上都運行的代理進程Borglet。Borg的全部組件都使用C++開發。

       我的解讀:咱們的雲平臺組件也都使用C++開發,基本屬於雲平臺慣例。不過,因爲Docker、Kubernetes、etcd等開源系統都是基於Golang開發,我最近正在學習Golang。

wKioL1Ym7X2jx0HpAAL6ddaVgJo719.jpg

       3.1 Borgmaster

       Borgmaster包含兩類進程:主Borgmaster進程和分離的調度器進程。主Borgmaster進程處理客戶端RPC;管理系統中全部對象Object的狀態機,包括machines、tasks、allocs;與Borglet通訊;提供webUI。

       Borgmaster邏輯上一個進程,可是擁有5個副本。每一個Borgmaster副本維護cell狀態的一分內存副本,cell狀態同時在高可用、分佈式、基於Paxos的存儲系統中作本地磁盤持久化存儲。一個單一的被選舉的master既是Paxos leader,也是狀態管理者。當cell啓動或者被選舉master掛掉時,系統會選舉Borgmaster,選舉機制按照Paxos算法流程進行。

       我的解讀:Borgmaster基於高可用、分佈式、基於Paxos的存儲系統進行元數據持久化和熱Borgmaster備份,以此實現Borg系統的高可用。關於這個基於Paxos的存儲系統,在Google內部應該就是Chubby,不過不知道爲什麼這裏沒有說起,難道還有新的系統?開源界etcd最近比較火,可是etcd沒有采用Paxos算法,而是使用更爲簡單且易於理解的raft。這裏仍是採用Paxos算法,本人暫時還認識不到替代Chubby的必要性。

       Borgmaster的狀態會定時設置checkpoint,具體形式就是在Paxos store中存儲週期性的鏡像snapshot和增量更改日誌。

       3.2 調度Scheduling

       看成業被提交,Borgmaster將其記錄到Paxos store中,並將做業的任務增長到等待隊列中。調度器異步瀏覽該隊列,並將任務分配給機器。調度算法包括兩個部分:可行性檢查和打分。

       可行性檢查,用於找到知足任務約束、具有足夠可用資源的一組機器;打分,則是在「可行機器」中根據用戶偏好,爲機器打分。用戶偏好主要是系統內置的標準,例如挑選具備任務軟件包的機器、分散任務到不一樣的失敗域中(出於容錯考慮)。

       我的解讀:在咱們的學術研究和工程實踐中,調度也分爲這兩個部分。咱們也將這個調度流程和約束有機結合起來,可行性檢查用於處理硬約束,其中具有足夠可用資源也能夠看做一種特殊的硬約束;打分用於處理軟約束,符合「儘可能知足軟約束」的原則。

       Borg使用不一樣的策略進行打分。實踐中,E-PVN(worst fit)會將任務分散到不一樣的機器上;best fit,會盡可能「緊湊」的使用機器,以減小資源碎片。Borg目前使用一種混合模型,儘可能減小「受困資源」。

       3.3 Borglet

       Borglet是運行在每臺machine上的本地Borg代理,管理本地的任務和資源。Borgmaster會週期性地向每個Borglet拉取當前狀態。這樣作更易於Borgmaster控制通訊速度,避免「恢復風暴」。

       爲了性能可擴展性,每一個Borgmaster副本會運行一個無狀態的link shard去處理與部分Borglet通訊。當Borgmaster從新選舉時,會從新分區。Borgmaster副本會聚合和壓縮信息,僅僅向被選舉master報告狀態機的不一樣部分,以此減小更新負載。

       若是Borglet多輪沒有響應資源查詢,則會被標記爲down。運行其上的任務會被從新調度到其餘機器。若是恢復通訊,則Borgmaster會通知Borglet殺死已經從新調度的任務,以此保證一致性。

       3.4 規模可擴展性Scalability

       咱們不肯定Borg中心化架構的可擴展性極限在哪裏;不過到目前爲止,每次接近極限,咱們都能設法消除它。一個Borgmaster能夠管理數千臺機器,任務到達率約爲每分鐘10K個任務。一個忙碌的Borgmaster使用10-14個CPUcore和50GB內存。

       我的解讀:這句話有點牛啊!對於分佈式領域的關鍵挑戰——可擴展性,Google人員說尚未真正遇到過極限。這句話的霸氣程度不亞於在酒桌上說「我歷來沒醉過」(哈哈哈哈),固然最關鍵的是人家不是嘴炮,人家真的作到了。

       爲了提高可擴展性,咱們將調度器分割爲獨立進程,這樣它能夠與Borgmaster並行進行操做。調度器具有多個副本,每一個調度器在cell狀態的副本上進行操做。它重複如下操做:從被選舉master中檢索狀態變動;更新本地狀態副本;進行調度、分配任務;將分配通知被選舉master。Master會檢查調度器的調度操做,若是發生調度衝突則再下一輪從新調度,不然接受並應用該調度結果。這套機制與Omega一文中的樂觀併發控制高度類似。此外,Borg最近支持爲不一樣負載類型使用不一樣調度器。

       我的解讀:Omega的核心思想就是採用樂觀併發控制,使得調度並行化,解決調度器可能成爲集羣系統性能瓶頸的問題,提升系統的可擴展性。根據上述描述,Borg多調度器併發調度採用了這種機制。

       爲了提升系統可擴展性,Borg調度器還做了幾種優化,分別是得分緩存(能夠將可行性檢查和打分結果緩存下來)、等價類(同一job中的task一般具備相似的約束,所以能夠將多個任務視爲一個等價類)、輕鬆隨機化(在大規模cell中計算全部機器的可行性和得分代價過高,能夠隨機遍歷直到找到一個「足夠好」的機器)。


4 可用性 Availability

       失敗在大規模系統中很是常見。本文列舉了Borg提升可用性的例子:

      (1)自動從新調度器被驅逐的任務;

      (2)爲了下降相關失敗,將任務分散到不一樣的失敗域中;

      (3)限制一個做業中任務的個數和中斷率;

      (4)限制任務從新調度的速率,由於不能區分大規模機器故障和網絡分區;

      (5)避免引起錯誤的任務-機器匹配對;

      (6)關鍵數據持久化,寫入磁盤。


5 利用率 Utilization

        本節首先經過實驗證實,混合部署(prod負載和non-prod負載)比獨立部署具備更高的利用率。實驗結果下圖。 

wKiom1Y1d0exfwQIAADhj6qvbrA158.jpg      

        隨後,結合實驗說明,幾種方法能夠提升集羣利用率,具體包括Cell sharing、Large cell、Fine-grained resource requests和Resource reclamation。前幾種方法都比較直觀,不作展開。Resource reclamation比較有意思,重點闡述。

       一個做業(job)能夠定義一個資源上限(resource limit),資源上限用於Borg決定用戶是否具備足夠的資源配額(quota)來提交做業(job),而且用於決定是否具備足夠的空閒資源來調度任務。由於Borg會kill掉一個嘗試使用更多RAM和disk空間資源(相比於其申請的資源)的task,或者節流CPU資源(相比於其要求的),因此用戶老是申請更多的資源(相比其實際全部的)。此外,一些任務偶爾會使用其全部資源,但大部分時間沒有。

       我的解讀:用戶老是會處於「心理安全」和負載高峯波動等緣由,申請較多的資源,但大部分時候,任務不會真正使用如此之多的資源。這就形成了資源浪費。

       對於能夠容忍低質量資源的工做(例如批處理做業),Borg會評估任務將使用的資源,並回收空閒資源。這個整個過程稱爲資源回收(resource reclamation)。評估過程稱爲任務預留(task reservation)。最初的預留值與其資源請求一致,而後300秒以後,會慢慢下降到實際使用率外加一個安全邊緣。若是利用率超過資源預留值,預留值會快速增加。

       這裏引用華爲鍾誠的圖片,直觀的代表實際使用資源、預留資源、資源上限的關係。


wKiom1Y1gGTiK89uAAgWfJ4iDG0958.jpg

6 隔離 Isolation

       包括安全隔離和性能隔離,這裏不作展開。


7 相關工做 Related work

        資源調度是熱點研究問題,具備許多相關研究。論文介紹了許多相關係統,我這裏找幾個重點系統進行簡要分析。

        7.1 Mesos

        Mesos經過resourceoffer機制,將資源管理和放置功能分開。Mesos的中央資源管理器(Mesos master)負責資源管理,多個框架(例如Hadoop、Spark)負責具體的任務放置(即任務調度)。Borg採用基於請求(request-offer)的機制,而非基於offer的機制,更易於系統擴展。

        7.2 YARN

        YARN是Hadoop中心化的集羣管理器。每一個應用都有一個管理器(AM)用於向中央資源管理器(RM)協商請求資源。這種機制相似於2008年之前Borg爲Google MapReduce分配資源的機制。

        7.3 阿里巴巴Fuxi

        Fuxi不是像Borg那樣把task調度到合適的machine上,而是「反向調度」,爲最近可用的machine匹配任務task。

        7.4 Omega

        Omega支持併發調度,其機制在前文3.4節已經介紹.

        7.5 Kubernetes

        建設Borg的許多工程師正在研發Kubernetes,並將Borg的經驗應用到Kubernetes之中。


8 經驗以及將來工做 Lessons and futurework

       介紹了一些經驗教訓。最後提到Google將繼續改進Borg,並將其中的經驗應用到Kubernetes之中。

       我的解讀:Borg是我一直關注和學習的系統,本文介紹了Borg的許多內容,涉及集羣管理的方方面面,能夠說信息量很大。好比,併發調度在本文中僅用了半節來描述,可是自己卻產出了Omega一篇完整的論文。

       另外,Google彷佛不喜歡對於其核心繫統進行開源,好比當年的MapReduce、GFS、BigTable、Chubby等都不是Google自行開源,只是開源社區根據其發表論文本身造的「大輪子」。並且你們推測開源版本在實現上可能與Google版本存在不一樣程度的差距。目前來看,Google也徹底沒有開源Borg的苗頭,可是Google開源了Kubernetes(同一撥人搞的,並汲取多年經驗),因此咱們在研讀Borg論文之餘,也要投身於Kubernetes的實踐當中啊!

相關文章
相關標籤/搜索