google集羣操做系統borg

1. Introduction

google服務器集羣的管理系統,相似於百度的Matrix,阿里的fuxi,騰訊的颱風平臺等等,還有開源的mesos java



Borg provides three main benefits: it c++

  1. hides the details of resource management and failure handling so its users can focus on application development instead;
  2. operates with very high reliability and availability, and supports applications that do the same; and
  3. lets us run workloads across tens of thousands of machines effectively.


2. The user perspective

borg主要面向於系統管理員和google開發者,這些用戶在borg上面運行他們的服務和應用程序,用戶以job的形式提交任務,每一個job包含一個或者多個tasks,每一個job運行在一個cell裏,cell是機器的集合,能夠理解爲是一個邏輯的IDC web


2.1 The workload

borg上運行的服務一般能夠分爲兩類: 算法

  1. prod:long-running服務,幾乎不停機,時延敏感,例如gmail,google docs,google搜索等等,另外還有一些google內部的基礎架構平臺,例如bigtable,GFS
  2. non-prod:batch型任務,時延不敏感,一般幾小時或者幾天便可跑完

這兩種不通類型的任務在borg的cell裏一般是混部的,同時又須要結合不一樣類型任務的特色,以及IDC屬性,等等作出不一樣的調度策略。例如end- user-facing服務利用率一般都會有一個固定的模式,白天的時候利用率很高,晚上機器又很閒,深夜可能幾乎沒什麼訪問量等等,另外Batch型任 務執行時間段,通常上來跑個幾分鐘,幾小時就完成任務了。等等。 服務器


borg最主要的目的,就是要提升機器的利用率。 網絡


在google內部,不少應用程序框架都是構建在borg之上的,例如mapreduce系統,FlumeJava,Millwheel,Pregel, 還有google的分佈式存儲服務,例如GFS,Bigtable,Megastore。像mapreduce,flumejava這種服 務,master和他們的job都是跑在borg上的,這裏的master和job區別於borg裏的master和job 架構

In a representative cell, prod jobs are allocated about 70% of the total CPU resources and represent about 60% of the total CPU usage; they are allocated about 55% of the total memory and represent about 85% of the total memory usage. 併發

2.2 Clusters and cells

數據中心 > 集羣  > cell app

A cluster usually hosts one large cell and may have a few smaller-scale test or special-purpose cells. We assiduously avoid any single point of failure. 中等規模的cell大約10k臺服務器左右,不包括測試cell,個人理解這些smaller-scale test cell的主要做用是小流量專用?每一個機器上可供調度的資源類型包括:cpu,內存,網絡,磁盤,甚至是處理器性能,類型,以及ssd,ip地址等等(我 的理解,對於某些類型的服務,是須要固定IP,而不容許隨意調度,例如存儲系統)。 負載均衡

用戶在提交job的時候申請資源,而後borg將它們調度到某機器上執行,監控他們的狀態,若是有必要在job的狀態failed後重啓它們

2.3 Jobs and tasks

job的屬性包括:名稱,owner,tasks,同時還包括一些調度的約束條件,例如處理器架構,os版本,ip地址等等,這些會影響borg-master調度的結果,固然這些條件不必定是強制約束的,分hard和soft兩種。

一個job只能跑在一個cell裏,每一個job會有N個task,每一個task運行期間會有多個進程,google並無使用虛擬機的方式來進行task之間的資源隔離,而是使用輕量級的容器技術cgroup。

task也有本身的屬性:資源需求和一個index,大部分時候一個job裏的全部task的資源需求都是同樣的。

Users operate on jobs by issuing remote procedure calls (RPCs) to Borg, most commonly from a command-line tool, other Borg jobs, or our monitoring systems

job是經過一個google本身實現的BCL語言來描述的,用戶能夠經過update的方式來更新job的描述文件,基於過程狀態機:


update過程是輕量的,非原子的,並且也是有可能會失敗的,Updates are generally done in a rolling fashion, and a limit can be imposed on the number of task disruptions (reschedules or preemptions) an update causes; any changes that would cause more disruptions are skipped

2.4 Allocs

alloc的本質上就是如今的容器,用來運行一個或者多個task,是task的運行環境,是一組資源的描述。只要是alloc裏的資源,無論有沒有使 用,都是已經分配了的(不容許給Batch類型的任務使用)。不過google也提到這個alloc是能夠併發使用,也能夠是重複利用的,併發的意思是說 多個task能夠同時跑在一個alloc裏,重複利用的意思是說一個task跑完了能夠繼續分配給另一個task使用。

併發使用能夠舉個例子:有兩個Job,一個job是web server實例,另外一個job是相關的一些task,例如日誌收集等等,這兩個job的task能夠同時跑在一個alloc裏,這樣日誌收集模塊能夠將 web server的日誌從local disk傳輸到分佈式文件系統裏。

一般一個task會關聯一個alloc,一個job會關聯一個alloc set

2.5 Priority, quota, and admission control

每一個task都會有一個優先級,高優先級的task能夠搶佔低優先級的task的資源,優先級是一個正整數,borg裏將這些優先級分紅4類:monitoring, production, batch, and best e ort

若是一個task被搶佔了,一般會調度到別的機器上繼續運行(同一個cell),we disallow tasks in the production priority band to preempt one another (單指production級別的仍是平級的job都不能相互搶佔?)


優先級肯定是否搶佔,quota決定是否能夠調度,quota表示所須要的資源,例如cpu,內存,網絡帶寬,磁盤配額等等

高優先級的task一般會比低優先級的task須要更多的quota,用戶申請資源的時候建議申請的比實際的資源佔用高一些,以確保task不會由於超發而被kill掉,特別是內存。另外,多申請些資源也能夠應對流量突發的狀況。

優先級0能夠有無窮大的quota,但一般會由於資源不足處於PENDING狀態而得不到調度


2.6 Naming and monitoring

僅僅建立和調度task運行是不夠的,從服務的角度來講,還須要有一個服務自動發現的機制,調度須要對用戶透明,作到用戶無感知。borg的Borg name service(BNS)就是爲了解決這個問題的。

borg爲每一個task建立一個BNS名字:cell名 + job名 + task索引,BNS名字和task的hostname + port會被持久化到chubby上,經過DNS解析,用戶憑BNS名字就能找到task,另外,Job的task數量和每一個task的健康狀態也會更新 到chubby上,這麼作的目的主要是爲了服務(這裏的服務是指job自己,多是個web server,也多是個分佈式存儲系統等等)的高可用,對用戶請求作負載均衡。


每一個task都會有一個內置的http服務,暴漏一些task的健康信息和各類性能指標,例如rpc時延等等。borg經過監控某個特定的url來決定task是否正常,若是不正常,好比http返回錯誤碼等,就重啓task。

google還有一個叫sigma的系統,用戶經過web界面就能夠直觀的觀察到用戶本身全部的job,cell狀態,甚至是task的健康信息,資源利 用率,日誌,狀態變動歷史等等。日誌是rotated的,避免打飛磁盤,另外,爲了調試方便,即便task運行結束後,log也會保留一段時間。

If a job is not running Borg provides a 「why pending?」 annotation, together with guidance on how to modify the job’s resource requests to better fit the cell. We publish guidelines for 「conforming」 resource shapes that are likely to schedule easily.


3. Borg architecture

每一個cell,包含一個控制器,borgmaster,同時cell裏的每一個機器,都運行着一個叫borglet的agent程序,無論是master和agent,都是用c++寫的

3.1 Borgmaster

每一個master包含兩個進程,一個主進程,一個調度進程,主進程處理用戶請求,例如建立job,查詢job等等,It also manages state machines for all of the objects in the system (machines, tasks, allocs, etc.), communicates with the Borglets, and offers a web UI as a backup to Sigma.

master有5個副本,每一個副本維護一份整個cell狀態的內存拷貝,並持久化到一個 highly-available, distributed, Paxos-based store 的本地磁盤上。經過paxos選出一個leader,負責處理cell狀態變動的全部請求,例如用戶提交一個job,中止一個job等。若是leader 宕機以後,chubby會選舉出另一個leader來提供服務,整個過程大概須要10s左右,若是cell規模很大,這個時間可能會持續到1分鐘。

master會按期checkpoint,snapshot + change log,這樣能夠將borgmaster恢復到以往任意的一個時間點,fixing it by hand in extremis; building a persistent log of events for future queries; and offline simulations.


TODO: Fauxmaster


3.2 Scheduling

當用戶提交一個job時,borgmaster會將job的元數據存儲到一個基於paxos的存儲系統裏,同時將job的task放到pending隊 列,如上面咱們提到的master架構,這個隊列會被另一個調度器進程按期異步地掃描,調度器進程一旦發現某個機器可以知足task的運行條件(例如資 源是否足夠,是否符合某些特定約束,處理器架構,內核版本等等),就將task調度到改機器上運行(注意:調度器調度的對象是task而不是job)

The scan proceeds from high to low priority, modulated by a round-robin scheme within a priority to ensure fairness across users and avoid head-of-line blocking behind a large job.

調度算法包括兩部分:

  1. feasibility checking: to find machines on which the task could run,
  2. scoring: which picks one of the feasible machines.

在feasibility checking階段,調度器檢查機器是否知足job的約束條件以及是否有足夠的可用資源(包括已經分配給低優先級job的資源,這些資源是能夠被搶佔的)。這裏可用資源的定義是:

  1. 若是task的優先級是prod的,那麼機器的可用資源須要減去task的limit
  2. 若是task的優先級是non-prod的,那麼機器上的可用資源只須要減去task已使用資源

在scoring階段,對機器進行打分,挑選出最合適的一個機器運行task,打分機制:

  1. 主要是根據borg內置的各類優化指標給候選調度結果打分,如最小化被搶佔的Task數,儘可能選擇已經下載了相同package的機器,下降硬件故障會影響的Task數,高低優先級混部等
  2. 也支持用戶直接傳入的一些偏好設置

打分模型主要有兩種:

  1. E-PVM,經過多個維度計算出一個單一的指標,可是實際操做上,E-PVM算法常常會將task打散到不一樣的機器上,這樣的好處是讓機器保留一點資源以應對峯值負載,壞處是資源碎片太多,會致使某些大型的task調度不上來。因此這種算法也叫worst fit
  2. 和worst fit對立的是best fit,就是儘量的將task緊湊地調度到一個機器上,好處是減小資源碎片,有利於大型做業的調度,壞處是對Batch型任務不友好,並且沒法應對任務的峯值負載

borg目前使用的是介於worst fit和best fit之間的一個變種:hybrid,儘量的減小閒置資源。

若是打分後選擇出來的機器可用資源不足,那麼搶佔就會發生,低優先級的做業首先會被踢掉,直到有足夠的空閒資源爲止。被搶佔的做業從新回到borgmaster的PENDING隊列裏等待遷移(若是得不到資源也有餓死的可能)。

因爲大部分包都是不會被修改的,因此borg在調度的時候還有一些優化的策略,爲了減小每次部署時下載包的時間(平均25s左右),borg在調度時會優先選擇那些已經存在這個包的機器。(因爲包不多被修改的特性,包是能夠被cache的)


3.3 Borglet

borglet是borg運行在單機上的agent程序,borglet的職責以下:

  1. 啓/停任務
  2. 若是任務失敗,負責任務重啓
  3. 任務之間的資源隔離,主要經過修改內核參數來實現,例如cgroup等等
  4. 日誌
  5. 監控&報告 任務狀態

borgmaster會按期輪詢全部的borglet,收集處理全部任務的運行狀態。master連agent的好處是有利於master控制負載,也有大部分分佈式系統是agent去連master的,好處是master的異常處理邏輯相對簡單。

前面咱們提到master是多副本的,leader負責向agent發送心跳,並根據agent的返回結果更新master的狀態,爲了提升性能,心跳的 內容可能會被壓縮,只傳輸diff。另外,若是一個borglet長期不響應master的心跳,則master會認爲該機器已經宕機,而且這機器上的所 有task都會被從新調度。若是borglet忽然恢復,則master會讓該機器kill掉全部的task。

master宕機並不影響borglet以及正在運行的task,另外,borglet進程掛了也是不影響正在運行的task的。

3.4 Scalability

在google裏,平均每一個borgmaster須要管理數千臺機器(前面咱們提過,一箇中等規模的cell大約是1w臺服務器左右),有些cell每分 鍾提交的任務數就超過1w個,一個繁忙的borgmaster甚至能夠用到10-14核,超過50G的內存。那麼google如何解決集羣規模不斷擴展帶 來的可擴展性問題呢?

早期的borgmaster只有一個簡單的,同步的循環過程:

  1. 接收用戶請求
  2. 調度任務
  3. 和borglets通信

爲了解決大集羣,borgmaster分離出一個調度進程,兩個進程並行協做,固然,災備是有的。

分離出來的調度進程職責是:

  1. 從elected master接收cell狀態 (including both assigned and pending work);
  2. 更新本地拷貝
  3. 預調度task(並不是真正的調度)
  4. 通知master確認調度結果(可能成功or失敗,例如過時)

這個過程和Omega裏的樂觀併發控制精神是一致的,borg最近還新增了一個feature,針對不一樣的workload類型使用不一樣的調度器

此外,borg針對可擴展性還作了幾個優化:

  1. Score caching: 給機器打分的開銷是很大的,並且一般機器的屬性靜態的,task的屬性也不會常常發生變化,因此,這個結果能夠cache,除非機器或者task屬性發生變化
  2. Equivalence classes: 同一個job裏的task一般都有一致的資源需求和約束條件,borg這將這些具備相同配置的task進行分類,打分的時候只按照分類給機器打分
  3. Relaxed randomization: 只隨機取一部分機器或者緯度來進行打分,以提高效率。

4. Availability

在一個大型的分佈式系統裏,單點故障是常態,運行在borg中的task,故障的緣由既多是機器宕機,也多是被搶佔調度,下圖是borg測試數據裏發現的被搶佔狀況:

除了應用程序自身須要考慮容災以外,borg在此方面也作了很多事情,來提升job的可用性:

  1. automatically reschedules evicted tasks, on a new machine if necessary
  2. reduces correlated failures by spreading tasks of a job across failure domains such as machines, racks, and power domains
  3. limits the allowed rate of task disruptions and the number of tasks from a job that can be simultaneously down during maintenance activities such as OS or machine upgrades
  4. uses declarative desired-state representations and idempotent mutating operations, so that a failed client can harmlessly resubmit any forgotten requests
  5. rate-limits finding new places for tasks from machines that become unreachable, because it cannot distinguish between large-scale machine failure and a network partition
  6. avoids repeating task::machine pairings that cause task or machine crashes
  7. recovers critical intermediate data written to local disk by repeatedly re-running a logsaver task (x2.4), even if the alloc it was attached to is terminated or moved to another machine. Users can set how long the system keeps trying; a few days is common
相關文章
相關標籤/搜索