共計 5165 個字符,預計需要花費 13 分鐘才能閱讀完成。
這篇文章主要介紹了 job 和 task 的概念是什么的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇 job 和 task 的概念是什么文章都會有所收獲,下面我們一起來看看吧。
1. 簡介
集群管理系統我們內部叫 Borg,它管理、調度、開始、重啟和監控谷歌運行的應用程序的生命周期。本文介紹它是怎么做到這些的。
Borg 提供了三個主要的好處:它(1)隱藏資源管理和故障處理細節,使其用戶可以專注于應用開發;(2)高可靠性和高可用性的操作,并支持應用程序做到高可靠高可用;(3)讓我們在跨數以萬計的機器上有效運行。Borg 不是第一個來解決這些問題的系統,但它是在這個規模,這種程度的彈性和完整性下運行的為數不多的幾個系統之一。
本文圍繞這些主題來編寫,包括了我們在生產環境運行十年的一些功力。
2. 用戶視角
Borg 的用戶是谷歌開發人員和系統管理員(網站可靠性工程師 SRE),他們運行谷歌應用與服務。用戶以 job 的方式提交他們的工作給 Borg,job 由一個或多個 task 組成,每個 task 含有同樣的二進制程序。一個 job 在一個 Borg 的 Cell 里面跑,一個 Cell 是包括了多臺機器的單元。這一節主要講用戶視角下的 Borg 系統。
2.1 工作負載
Borg Cell 主要運行兩種異構的工作負載。第一種是長期的服務,應該“永遠”運行下去,并處理短時間的敏感請求(幾微秒到幾百毫秒)。這種服務是面向終端用戶的產品如 Gmail、Google Docs、網頁搜索,內部基礎設施服務(例如,Bigtable)。第二種是批處理任務,需要幾秒到幾天來完成,對短期性能波動不敏感。在一個 Cell 上混合運行了這兩種負載,取決于他們的主要租戶(比如說,有些 Cell 就是專門用來跑密集的批處理任務的)。工作負載也隨著時間會產生變化:批處理任務做完就好,終端用戶服務的負載是以每天為周期的。Borg 需要把這兩種情況都處理好。
Borg 有一個 2011 年 5 月的負載數據[80],已經被廣泛的分析了[68,26,27,57,1]。
最近幾年,很多應用框架是搭建在 Borg 上的,包括我們內部的 MapReduce[23]、flumejava[18]、Millwheel[3]、Pregel[59]。這中間的大部分都是有一個控制器,可以提交 job。前 2 個框架類似于 YARN 的應用管理器 [76]。我們的分布式存儲系統,例如 GFS[34] 和他的后繼者 CFS、Bigtable[19]、Megastore[8]都是跑在 Borg 上的。
在這篇文章里面,我們把高優先級的 Borg 的 jobs 定義為生產(prod),剩下的是非生產的(non-prod)。大多長期服務是 prod 的,大部分批處理任務是 non-prod 的。在一個典型的 Cell 里面,prod job 分配了 70% 的 CPU 資源然后實際用了 60%;分配了 55% 的內存資源然后實際用了 85%。在 $5.5 會展示分配和實際值的差是很重要的。
2.2 集群和 Cell
一個 Cell 里面的所有機器都屬于單個集群,集群是由高性能的數據中心級別的光纖網絡連接起來的。一個集群安裝在數據中心的一座樓里面,n 座樓合在一起成為一個 site。一個集群通常包括一個大的 Cell 還有一些小的或測試性質的 Cell。我們盡量避免任何單點故障。
在測試的 Cell 之外,我們中等大小的 Cell 大概包括 10000 臺機器;一些 Cell 還要大很多。一個 Cell 中的機器在很多方面都是異構的:大小(CPU,RAM,disk,network)、處理器類型、性能以及外部 IP 地址或 flash 存儲。Borg 隔離了這些差異,讓用戶單純的選擇用哪個 Cell 來跑任務,分配資源、安裝程序和其它依賴、監控系統的健康并在故障時重啟。
(譯者:Cell 其實就是邏輯上的集群)
2.3 job 和 task
一個 Borg 的 job 的屬性有:名字、擁有者和有多少個 task。job 可以有一些約束,來指定這個 job 跑在什么架構的處理器、操作系統版本、是否有外部 IP。約束可以是硬的或者軟的。一個 job 可以指定在另一個 job 跑完后再開始。一個 job 只在一個 Cell 里面跑。
每個 task 包括了一組 linux 進程,跑在一臺機器的一個容器內 [62]。大部分 Borg 的工作負載沒有跑在虛擬機(VM) 里面,因為我們不想付出虛擬化的代價。而且,Borg 在設計的時候還沒硬件虛擬化什么事兒哪。
task 也有一些屬性,包括資源用量,在 job 中的排序。大多 task 的屬性和 job 的通用 task 屬性是一樣的,也可以被覆蓋 —— 例如,提供 task 專用的命令行參數,包括 CPU 核、內存、磁盤空間、磁盤訪問速度、TCP 端口等等,這些都是可以分別設置并按照一個好的粒度提供。我們不提供固定的資源的單元。Borg 程序都是靜態編譯的,這樣在跑的環境下就沒有依賴,這些程序都被打成一個包,包括二進制和數據文件,能被 Borg 安裝起來。
用戶通過 RPC 來操作 Borg 的 job,大多是從命令行工具,或者從我們的監控系統 ($2.6)。大多 job 描述文件是用一種申明式配置文件 BCL — GCL[12] 的一個變種,會產生一個 protobuf 文件[67]。BCL 有一些自己的關鍵字。GCL 提供了 lambda 表達式來允許計算,這樣就能讓應用在環境里面調整自己的配置。上萬個 BCL 配置文件超過一千行長,系統中累計跑了了千萬行 BCL。Borg 的 job 配置很類似于 Aurora 配置文件[6]。
圖 2 展現了 job 的和 task 的狀態機和生命周期。
用戶可以在運行時改變一個 job 中的 task 的屬性,通過推送一個新的 job 配置給 Borg。這個新的配置命令 Borg 更新 task 的規格。這就像是跑一個輕量級的,非原子性的事務,而且可以在提交后輕易再改回來。更新是滾動式的,在更新中可以限制 task 重啟的數量,如果有太多 task 停掉,操作可以終止。
一些 task 更新,例如更新二進制程序,需要 task 重啟;另外一些例如修改資源需求和限制會導致這個機器不適合跑現有的 task,需要停止 task 再重新調度到別的機器上;還有一些例如修改優先級是可以不用重啟或者移動 task 的。
task 需要能夠接受 Unix 的 SIGTERM 信號,在他們被強制發送 SIGKILL 之前,這樣就有時間去做清理、保存狀態、結束現有請求執行、拒絕新請求。實際的 notice 的 delay bound。實踐中,80% 的 task 能正常處理終止信號。
2.4 Allocs
Borg 的 alloc(allocation 的縮寫)是在單臺機器上的一組保留的資源配額,用來讓一個或更多的 task 跑;這些資源一直分配在那邊,無論有沒有被用。allocs 可以被分配出來給未來的 task,用來保持資源在停止一個 task 和重啟這個 task 之間,用來聚集不同 jobs 的 tasks 到同一臺機器上——例如一個 web server 實例和附加的,用于把 serverURL 日志發送到一個分布式文件系統的日志搜集實例。一個 alloc 的資源管理方式和一臺機器上的資源管理方式是類似的;多個 tasks 在一個 alloc 上跑并共享資源。如果一個 alloc 必須被重新定位到其他的機器上,那么它的 task 也要跟著重新調度。
一個 alloc set 就像一個 job:它是一組 allocs 保留了多臺機器上的資源。一旦 alloc set 被創建,一個或多個 jobs 就可以被提交進去跑。簡而言之,我們會用 task 來表示一個 alloc 或者一個 top-level task(一個 alloc 之外的),用 job 來表示一個 job 或者 alloc set。
2.5 優先級、配額和管理控制
當有超量的工作負載在運行的時候會發生什么事情?我們的解決方案是優先級和配額。
所有 job 都有優先級,一個小的正整數。高優先級的 task 可以優先獲取資源,即使后面被殺掉。Borg 定義了不重疊的優先級段給不同任務用,包括(優先級降序):監控、生產、批任務、高性能(測試或免費)。在這篇文章里面,prod 的 jobs 是在監控和生產段。
雖然一個降級的 task 總會在 cell 的其他地方找到一席之地。降級瀑布也有可能會發生,就是一個 task 降下來之后,把下面運行的 task 再擠到別的機器上,如此往復。為了避免這種情況,我們禁止了 prod 級 task 互相排擠。合理粒度的優先級在其他場景下也很有用——MapReduce 的 master 跑的優先級比 worker 高一點,來保證他們的可用性。
優先級是 jobs 的相對重要性,決定了 jobs 在一個 cell 里面是跑還是等 (pending)。配額則是用來決定 jobs 是否運行被調度。配額就是一組資源(CPU, RAM, disk) 的數量在一個指定的優先級、一個指定的時間段(月這個量級)。數量決定了這個用戶的 job 可以用的最多資源(例子:20TB 內存和 prod 優先級從現在到 7 月在 xx cell 內)。配額檢查是管理控制的一部分,不是調度層的:配額不足的任務在提交的時候就會被拒絕。
高優先級的配額總是花費的比低優先級要多。prod 級的配額是被限制為一個 cell 里面實際的資源量,所以用戶提交了 prod 級的 job 的配額時,可以期待這個 job 一定會跑,去掉一些碎片外。即使這樣,我們鼓勵用戶多買一點比自己需要多一點的配額,很多用戶超買是因為他們的應用程序的用戶數量增長后需要的配額就大了。對于超買,我們的應對方案是低優先級資源的超售:所有用戶在 0 優先級都可以用無限的配額,雖然在實際運行中這種情況很難跑起來。一個低優先級的 job 在資源不足時會保持等 (pending) 狀態。
配額分配在 Borg 系統之外,和我們的物理資源計劃有關。這些資源計劃在不同的數據中心產生不同的價格和配額。用戶 jobs 只在有足夠配額和足夠優先級之后才能啟動。配額的使用讓 Dominant Resource Fairness(DRF)[29, 35, 36, 66]不是那么必要了。
Borg 有一個容量系統給一些特殊權限給某些用戶,例如,允許管理員刪除或修改 cell 里面的 job,或者允許用戶區訪問特定的內核特性或者讓 Borg 對自己的 job 不做資源估算($5.5)。
2.6 命名和監控
光是創建和部署 task 是不夠的:一個服務的客戶端和其他系統需要能找到它們,即使它換了個地方。為了搞定這一點,Borg 創造了一個穩定的“Borg name Service”(BNS)名字給每個 task,這個名字包括了 cell 名字,job 名字,和 task 編號。Borg 把 task 的主機名和端口寫入到一個持久化高可用文件里,以 BNS 名為文件名,放在 Chubby[14]上。這個文件被我們的 RPC 系統使用,用來發現 task 的終端地址。BNS 名稱也是 task 的 DNS 名的基礎構成部分,所以,cc cell 的 ubar 用戶的 jfoo job 的第 50 個 task 的 DNS 名稱會是 50.jfoo.ubar.cc.borg.google.com。Borg 同時還會把 job 的大小和 task 的健康信息寫入到 Chubby 在任何情況改變時,這樣負載均衡就能知道怎么去路由請求了。
幾乎所有的 Borg 的 task 都會包含一個內置的 HTTP 服務,用來發布健康信息和幾千個性能指標 (例如 RPC 延時)。Borg 監控這些健康檢查 URL,把其中響應超時的和 error 的 task 重啟。其他數據也被監控工具追蹤并在 Dashboards 上展示,當服務級別對象(SLO) 出問題時就會報警。
用戶可以使用一個名叫 Sigma 的 web UI,用來檢查他們所有的 job 狀態,一個特殊的 cell,或者深入到某個 job 的某個 task 的資源用率,詳細日志,操作歷史,和最終命運。我們的應用產生大量的日志,都會被自動的滾動來避免塞滿硬盤,會在一個 task 結束后保留一小段時間用來 debug。如果一個 job 沒有被跑起來,Borg 會提供一個為什么掛起的解釋,指導用戶怎么修改這個 job 的資源需求來符合目前這個 cell 的情況。我們發布資源的使用方針,按照這個方針來做就容易被調度起來。
Borg 記錄所有的 job 提交和 task 時間,以及每 task 的資源使用細節在基礎存儲服務里面。這個存儲服務有一個分布式的只讀的 SQL-like 的交互式接口,通過 Dremel[61]提供出來。這些數據在實時使用、debug、系統查錯和長期容量規劃上都很有用。這些數據也是 Google 集群負載追蹤的數據來源之一[80].
所有這些特性幫助用戶理解和 debug Borg 的行為和管理他們的 job,并且幫助我們的 SRE 每個人管理超過上萬臺機器。
關于“job 和 task 的概念是什么”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“job 和 task 的概念是什么”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注丸趣 TV 行業資訊頻道。