1. 什么是在離線混部
混部概念中將應(yīng)用類型分為在線業(yè)務(wù)和離線業(yè)務(wù)兩種。
在線和離線業(yè)務(wù)如何劃分?在百度內(nèi)部,我們認(rèn)為在線業(yè)務(wù)特點(diǎn)包括但不限于:運(yùn)行時間長,延時敏感,對穩(wěn)定向要求較高,服務(wù)不穩(wěn)定業(yè)務(wù)會立馬感知并且?guī)頁p失,有明顯的波峰波谷,白天高,深夜低,比如廣告搜索業(yè)務(wù);而離線業(yè)務(wù)的特點(diǎn)包括但不限于非延時敏感,可重試,運(yùn)行時間一般較短在幾十分鐘左右,內(nèi)部一般為大數(shù)據(jù)計(jì)算,機(jī)器學(xué)習(xí)等服務(wù)。
在線業(yè)務(wù)以搜索為例,白天用戶工作學(xué)習(xí)時查詢量會非常大,但是當(dāng)大部分用戶夜間休息時,查詢量相對白天就會變得非常小,此時我們就可以引入離線業(yè)務(wù)。離線業(yè)務(wù)沒有嚴(yán)格的時間要求,隨時都能跑,用戶關(guān)心的是任務(wù)能不能跑完,對于什么時候跑完并沒有太大的需求,同時如果單機(jī)上資源有沖突,此時我們會壓制離線業(yè)務(wù),甚至?xí)?qū)逐離線業(yè)務(wù),這對用戶是無感的,計(jì)算平臺重新拉起任務(wù),繼續(xù)計(jì)算。
因此,在線型業(yè)務(wù)和離線業(yè)務(wù)具備資源互補(bǔ)的特點(diǎn),從時間上和對資源的容忍度上可以完美的結(jié)合到一起。一方面,在線業(yè)務(wù)的優(yōu)先級更高,單機(jī)和調(diào)度層面會優(yōu)先保障在線的資源,可能會對離線進(jìn)行壓制和驅(qū)逐,另一方面,對于離線任務(wù)來說,壓制和驅(qū)逐對用戶是無感的,只需要保證任務(wù)順利完成,有很高的容忍度。
簡單來說,將在線業(yè)務(wù)和離線任務(wù)混合混部到相同物理資源上,通過資源隔離、調(diào)度等控制手段 , 充分使用資源,同時保證服務(wù)的穩(wěn)定性,我們稱這樣的技術(shù)為“混部”。
2. 資源利用率為何不高?
純在線業(yè)務(wù)集群的平均利用率普遍不高,百度應(yīng)用混部技術(shù)之前,在線業(yè)務(wù)集群CPU利用率普遍在20%左右,造成這種現(xiàn)象主要由一下幾種原因:2.1 潮汐現(xiàn)象和冗余在線業(yè)務(wù)在申請資源的時候,一般是按照最高峰值評估資源去申請資源,同時還會上調(diào)一些,這就導(dǎo)致了業(yè)務(wù)對資源預(yù)估不準(zhǔn),申請的資源遠(yuǎn)大于實(shí)際使用資源。甚至可能會部署多個副本作為災(zāi)備。此時的低峰時利用率就會非常低,導(dǎo)致整體利用率不高。2.2 在離線分池一般來說機(jī)房規(guī)劃的時候有一個非常大的特點(diǎn),就是離線機(jī)房與在線機(jī)房分離做規(guī)劃。舉個例子,假如我們在寧夏做一個機(jī)房,這個時候肯定會考慮做一個離線機(jī)房,因?yàn)樵诰€機(jī)房需要考慮網(wǎng)民請求地域分布的問題,要獲得最好的訪問優(yōu)化體驗(yàn)以及訪問速度,勢必需要在一些訪問熱點(diǎn)上去做自己的在線機(jī)房規(guī)劃,比如北京、上海、廣州等。而對于離線機(jī)房來說不用關(guān)心這些,它最在乎的是如何提升計(jì)算和儲存的資源和基礎(chǔ)設(shè)施的規(guī)模,所以在線業(yè)務(wù)和離線業(yè)務(wù)本身的資源需求和特點(diǎn)不一樣,資源利用率非常不均衡。常態(tài)表現(xiàn)就是在線利用率低,離線利用率高,且常態(tài)資源不足。針對以上場景,我們通過在離線混部技術(shù)將在離線資源統(tǒng)一資源池,把離線作業(yè)部署在在線資源池節(jié)點(diǎn)上,充分利用機(jī)器資源,達(dá)到了提升資源利用率的目的。
3.百度云原生混部詳解
隨著 Kubernetes(以下簡稱「K8s」) 生態(tài)的蓬勃發(fā)展,百度很多業(yè)務(wù)已經(jīng)搭建并且運(yùn)維了自己的諸多 K8s 集群,同時也遇到了一些問題,比如上面所說的資源利用率不高。我們根據(jù)內(nèi)部積累混部經(jīng)驗(yàn)對 K8s 進(jìn)行在離線混部原生化改造,做到了零入侵K8s,可移植,可支持大規(guī)模集群。

混部系統(tǒng)架構(gòu)圖
3.1 如何做到資源復(fù)用?
原生 K8s 基于靜態(tài)視圖分配

上圖顯示了一個節(jié)點(diǎn)的 CPU 使用率和分配率,分配率為89%, 使用率在0-16點(diǎn)之間都在20%以下,17點(diǎn)開始是用量高峰,在30-40%之間。可以看出 request 和 used 之間有大量的資源處于閑置狀態(tài),如果想讓這部分資源可以重復(fù)利用起來,就需要調(diào)度更多的 Pod 上去,但是從 K8s 調(diào)度器視角來看,已經(jīng)沒有更多的 CPU 分給 Pod了。
如果部署 request 和 limit 都不填寫的 Pod,此時它可以被調(diào)度,但是 K8s 針對這種 BestEffort 的 Pod 不會根據(jù)用量調(diào)度,可能會被調(diào)度到一個實(shí)際很繁忙的節(jié)點(diǎn)上,非但無法起到提升使用率的效果,可能還會加劇節(jié)點(diǎn)上服務(wù)的延遲。
動態(tài)資源視圖
針對 K8s 無法根據(jù)資源使用量分配資源,我們引入了動態(tài)資源視圖。
在混部調(diào)度中,在線和離線使用相同的物理資源,在線看到的資源視圖和離線看到的資源視圖相互獨(dú)立。在線業(yè)務(wù)看到的可用資源依舊為整機(jī)資源進(jìn)行靜態(tài)分配,離線看到的可用資源為整機(jī)資源減去在線作業(yè)已經(jīng)使用的資源。

從圖中可以看出,在線申請用量和在線usage之間存在很大的差異,主要是由于研發(fā)同學(xué)部署業(yè)務(wù)選擇容器資源規(guī)格時,帶有一定的盲目性,申請量高于實(shí)際使用資源量或者按照超出峰值用量申請。混部離線可以復(fù)用這部分可回收資源,通過快速填充離線作業(yè),把這部分資源利用起來。
高中優(yōu)(在線)為靜態(tài)分配 ∑High request + ∑Medium request <= Host Quota
動態(tài)計(jì)算低優(yōu)(離線)可用量 Low Quota = Host Quota - ∑High used - ∑Medium used
注:以上是理想情況下的公式,實(shí)際應(yīng)用中需要對離線使用量設(shè)置一個上限,此處排除了上限造成的影響。下面會有單機(jī)資源管理的說明。
由于 K8s 是靜態(tài)分配,在 K8s 的 QOS 模型中 BestEffort 是不占用 request 的,即使一個 node 上即使資源已經(jīng)分配完,但是 BestEffort 類型的資源依然可以調(diào)度上去,所以我們復(fù)用了 BestEffort 模型給離線任務(wù)使用,如上文架構(gòu)圖所示,這樣有以下的優(yōu)點(diǎn):
- 解決了在離線視圖沖突問題,離線使用的 BestEffort 模型,對在線不可見
- 兼容社區(qū)組件,比如 cadvisor 可以直接使用
- 無需修改已有組件,包括 kubelet containerd runc,侵入性小,可以直接安裝混部系統(tǒng),享受混部帶來的資源效能提升。
3.2 優(yōu)先級
由于在離線業(yè)務(wù)同時部署在相同節(jié)點(diǎn)上可能會產(chǎn)生干擾,我們從調(diào)度和單機(jī)兩個方面對在線離線做了優(yōu)先級區(qū)分。
大的優(yōu)先級分為(高,中,低)三種,其中高優(yōu)中優(yōu)為在線業(yè)務(wù),低優(yōu)為離線業(yè)務(wù)。每個優(yōu)先級優(yōu)化分若干小優(yōu)先級。
首先看一下 K8s 的 QOS 模型
- Guaranteed : 當(dāng) Pod 中所有 Container 的 request == limit 時
- Burstable : 當(dāng) Pod 中存在 Container 的 request != limit 時
- BestEffort : 當(dāng) Pod 中所有 Container 均未設(shè)置 request, limit 時
對比 K8s 模型,百度混部調(diào)度器做了如下擴(kuò)展:
3.3 資源隔離
由于在離線混部是將在線業(yè)務(wù)和離線任務(wù)混合混部到相同物理資源上,所以在離線業(yè)務(wù)由于流量激增,出現(xiàn)資源爭搶時,如何保證在線的SLA不受影響,并且在保證在線服務(wù)的SLA時,也要保證離線任務(wù)的整體質(zhì)量,保證離線作業(yè)的成功率和耗時。
CPU
cpuset 編排
針對于需要綁核的在線業(yè)務(wù),單機(jī)上可以感知到 CPU 拓?fù)洌恍枰?kubelet 開啟綁核機(jī)制,可以直接進(jìn)行綁核,會將在線業(yè)務(wù)盡量綁在同一 NUMA node 上,避免跨 node 通信延遲。
NUMA 調(diào)度
NUMA 是一種內(nèi)存管理技術(shù),在 NUMA 架構(gòu)下 CPU 被劃分為多個 node,每個 node 都有各自的 CPU core 和 local memory,node core 中的進(jìn)程訪問 local memory 和 remote memory 的代價(jià)是不一樣的。節(jié)點(diǎn)的所有內(nèi)存對于本節(jié)點(diǎn)所有的 CPU 都是等同的,對于其他節(jié)點(diǎn)中的所有 CPU 都不同。因此每個 CPU 可以訪問整個系統(tǒng)內(nèi)存,但是訪問本地節(jié)點(diǎn)的內(nèi)存速度最快(不經(jīng)過互聯(lián)模塊),訪問非本地節(jié)點(diǎn)的內(nèi)存速度較慢(需要經(jīng)過互聯(lián)模塊),即CPU 訪問內(nèi)存的速度與節(jié)點(diǎn)的距離有關(guān)。
針對開啟了 NUMA 的節(jié)點(diǎn),我們感知 NUMA 架構(gòu),將在線業(yè)務(wù)綁在同一 NUMA 上,提升在線業(yè)務(wù)的性能,并且感知 NUMA 節(jié)點(diǎn)的負(fù)載,當(dāng) node 之間出現(xiàn)明顯的不平衡時,進(jìn)行重調(diào)度。
離線調(diào)度器
在線業(yè)務(wù)要求實(shí)時性高,延遲低;為了保證低延遲,CPU 負(fù)載不會打的特別高,當(dāng) CPU 負(fù)載升高時,在線間干擾會導(dǎo)致延時增大。而離線業(yè)務(wù)一般 CPU 利用率高,但是重吞吐不重延時。所以如果能滿足在線的延時保障,在線和離線跑在一個核上不會對在線造成干擾,那么可以極大的提升資源利用率。
按照現(xiàn)在通用的 linux 內(nèi)核調(diào)度器調(diào)度算法,無法給在線服務(wù)做 CPU 的強(qiáng)保障,無法區(qū)分在離線業(yè)務(wù),會導(dǎo)致在線無法搶占離線 CPU,并且在負(fù)載均衡時,因?yàn)闊o法區(qū)分在離線業(yè)務(wù),可能在線業(yè)務(wù)會分配到相同的核上,無法打散。導(dǎo)致性能下降。
離線調(diào)度器是一種離線任務(wù)專用的CPU調(diào)度算法,從調(diào)度器上分開,在線調(diào)度器看不到離線任務(wù)。在線調(diào)度器先于離線調(diào)度器進(jìn)行任務(wù)調(diào)度,存在在線任務(wù)時,離線得不到調(diào)度。所以對于在線任務(wù)來說,可以達(dá)到混部前相近的CPU 質(zhì)量。

內(nèi)存
Linux 系統(tǒng)會經(jīng)常執(zhí)行一些寫日志、生成備份文件的工作,當(dāng)這些文件比較大時相應(yīng)的 cache 就會占用大量的系統(tǒng)內(nèi)存,而且這些類型的 cache 并不會被經(jīng)常訪問,所以系統(tǒng)會定期將這些 cache flush 到磁盤中。Linux 會通過cache 回收算法進(jìn)行回收。這會造成兩個問題:
1.容器的 page cache 得不到回收,它依賴于容器管理 page cache 的機(jī)制是需要才去回收的方式,即沒有后臺回收,每次都是分配時候發(fā)現(xiàn)到達(dá) limit 了,在 alloc 的時候出發(fā)回收,如果業(yè)務(wù)壓力較大,分配的速度大于回收的速度,就可能出現(xiàn) OOM 的問題
2.cache 回收時并不會區(qū)分在線離線業(yè)務(wù),會導(dǎo)致在線業(yè)務(wù)的 cache 可能會被先于離線 cache 回收掉,如果在線有大量的讀 cache 行為,會造成 cache 命中降低,直接進(jìn)行讀盤操作,會導(dǎo)致在線業(yè)務(wù)的性能下降,甚至?xí)?dǎo)致IO 夯住。
為了解決以上的問題,我們新增了背景回收機(jī)制,背景回收指的是異步回收 cache,根據(jù)在線離線的 QOS 不同,設(shè)置不同的背景回收水位,優(yōu)先回收離線業(yè)務(wù)的 cache。
- 每個容器后臺周期自動回收自己產(chǎn)生的 page cache
- 每個容器都可以設(shè)置開關(guān)和自己的高低水位線
網(wǎng)絡(luò)層面我們也開發(fā)了容器級別的出入網(wǎng)帶寬限制和流量打標(biāo)等 Cgroup 子系統(tǒng),可以對離線進(jìn)行流量限制。
更多的內(nèi)核隔離見下圖:
基于 eBPF 的動態(tài)策略
現(xiàn)有的內(nèi)核隔離策略都是基于 QOS,創(chuàng)建容器時進(jìn)行 cgroup 配置,由內(nèi)核進(jìn)行統(tǒng)一的資源管理,但是某些高敏業(yè)務(wù)在最高優(yōu)先級的 QOS 下也無法保證其特定資源,或者需要某一緯度的資源需要高優(yōu)保證,此時通用隔離策略無法滿足。
另外由于隔離調(diào)度策略是全局統(tǒng)一的策略,業(yè)務(wù)如果想根據(jù)自身特點(diǎn)修改一些隔離能力,只能由業(yè)務(wù)反饋平臺,平臺對底層進(jìn)行修改,周期較長,并且全局應(yīng)用的隔離能力可能會對離線或者其他業(yè)務(wù)造成誤傷,所以把隔離提升到用戶態(tài)更符合業(yè)務(wù)需求。
針對這樣的場景,由于 eBPF 穩(wěn)定,安全,高效,并有可熱加載/卸載 eBPF 程序,無需重啟 Linux 系統(tǒng)的特性,我們基于 eBPF 開發(fā)了定制策略,可以實(shí)時下發(fā),實(shí)時生效,侵入性小,不需要對業(yè)務(wù)既有服務(wù)和平臺側(cè)進(jìn)行修改。可以在用戶態(tài)針對某些業(yè)務(wù)進(jìn)行定制化隔離策略更新,達(dá)到服務(wù)可以無差別混部的目標(biāo)。
單機(jī)資源管理
在混部時,離線可以占用多少資源一直是一個問題。機(jī)型不同,在線服務(wù)的敏感度不同,離線業(yè)務(wù)占用的資源多少對在線造成的影響也不盡相同,針對這種情況,我們對集群緯度,池(具有相同特性的一批機(jī)器)緯度,節(jié)點(diǎn)緯度對離線可用資源上限做了限制,其中粒度最小優(yōu)先級最高。
以 CPU 為例,如下圖:

我們設(shè)置了整機(jī)的 CPU 閥值X,當(dāng)整機(jī) CPU 用量趨近或超過一定用量,比如X=50%時,會壓縮離線使用的CPU資源。
列舉一個簡單的公式:
Offline Quota = Host Quota * X - ∑NotOffline Used
Offline Free = Offline Quota - ∑Offline used
同樣,對于 Memory,IO和網(wǎng)絡(luò)我們也做了同樣的限制。這樣我們可以根據(jù)不同的機(jī)型和業(yè)務(wù)很方便的調(diào)整離線的用量,避免在線用量升高時性能受到影響。
3.4 高性能調(diào)度器
在線和離線業(yè)務(wù)的調(diào)度需求是不一樣的,在線一般為常駐服務(wù),不會頻繁變更,對調(diào)度器要求較低。但是離線任務(wù)由于具有運(yùn)行時間短(幾分鐘到幾小時),任務(wù)多的特點(diǎn),以 K8s 默認(rèn)調(diào)度器的調(diào)度性能不足以支撐離線任務(wù)的調(diào)度。所以我們開發(fā)了高性能的離線調(diào)度器,計(jì)算可以達(dá)到5000 ops。

如上圖所示,我們調(diào)度了15W個 Pod,計(jì)算性能可以達(dá)到5k ops, 為了防止調(diào)度速度過快,對 ETCD 和整個集群造成壓力,我們限制了binding速度為1500 ops。
3.5 資源畫像
單機(jī)資源隔離是針對已經(jīng)調(diào)度到節(jié)點(diǎn)上的任務(wù)進(jìn)行隔離,如果檢測到離線任務(wù)對在線產(chǎn)生一定的影響后,會很快響應(yīng)對離線任務(wù)進(jìn)行壓制和驅(qū)逐的操作。這樣會影響離線任務(wù)的穩(wěn)定性。針對這種場景,如果在調(diào)度時可以預(yù)測到節(jié)點(diǎn)上未來一段時間的在線使用量,可以針對性的調(diào)度離線任務(wù)。
對比實(shí)時計(jì)算的資源模型,假設(shè)離線作業(yè)的運(yùn)行時間為1小時,如果資源模型使用實(shí)時的資源視圖,如果在線作業(yè)會在半個小時候用量升高,那么當(dāng)離線作業(yè)運(yùn)行半個小時之后,資源被在線壓制,運(yùn)行質(zhì)量受影響。
我們預(yù)測了未來1小時窗口內(nèi)的在線資源用量,調(diào)度適當(dāng)?shù)碾x線任務(wù)上去,即可確保任意離線作業(yè)運(yùn)行過程中資源不受任何壓制,從而達(dá)到提升運(yùn)行質(zhì)量的目的。
如何提供更穩(wěn)定的超發(fā)資源,則取決于我們資源預(yù)測的準(zhǔn)確度是什么樣的。
不僅離線調(diào)度需要資源畫像,在線調(diào)度也需要資源畫像,通過資源畫像可以有效的避免熱點(diǎn)產(chǎn)生。
- 對于在線調(diào)度來說,調(diào)度的主要目標(biāo)是提升服務(wù)的可用性,在調(diào)度時使用資源畫像來預(yù)測未來一個周期內(nèi)的用量,可以避免熱點(diǎn)問題(某一緯度的資源用量過高),并且在重調(diào)度時也可以規(guī)避熱點(diǎn)問題。
- 對于離線調(diào)度來說,調(diào)度的主要目標(biāo)是提升集群的吞吐,降低作業(yè)的排隊(duì)時間和執(zhí)行時間,所以資源畫像可以提升離線作業(yè)的穩(wěn)定性,避免驅(qū)逐重新調(diào)度和資源壓制導(dǎo)致執(zhí)行時間過長。
4.未來展望
百度目前混部規(guī)模數(shù)十萬臺,它的混部集群 CPU 利用率比在線利用率提升 40%—80%,累計(jì)節(jié)省近10萬臺服務(wù)器。
未來百度混部的主要目標(biāo)是繼續(xù)擴(kuò)大混部的規(guī)模,更大規(guī)模地節(jié)約資源成本,可以支持更多的負(fù)載類型,不局限于在離線混部,要做到無差別混部。
- 在單機(jī)隔離方面,支持更多的業(yè)務(wù)進(jìn)入混布,在檢測沖突和資源隔離方面做的更好。
- 調(diào)度方面做更有計(jì)劃的調(diào)度,資源畫像更加精細(xì)化,調(diào)度時可以更精準(zhǔn)的預(yù)測熱點(diǎn)概率,優(yōu)化調(diào)度能力,減少熱點(diǎn)率。
并在以下方向投入更多的力量:
- 內(nèi)核可編程技術(shù):
通過 eBPF 可觀測技術(shù)的創(chuàng)新,實(shí)現(xiàn)混部容器負(fù)載性能的近距離觀察,達(dá)到進(jìn)一步無損高密度混
利用 eBPF 熱加載/卸載的特性,可以用戶態(tài)下發(fā)隔離策略,快速的解決高敏的資源質(zhì)量問題
- 異構(gòu):更好的支持GPU等異構(gòu)資源混部,提高異構(gòu)資源效能與彈性,大幅降低GPU成本。
- 容器虛機(jī)融合:解決高密機(jī)型共享內(nèi)核混部的瓶頸。
- 多云混部:結(jié)合公有云進(jìn)行極致的彈性,例如結(jié)合彈性競價(jià)實(shí)例,基于用戶對價(jià)格的敏感度設(shè)置,自動納入或者摘除競價(jià)實(shí)例,用于離線業(yè)務(wù)運(yùn)行或混部,實(shí)現(xiàn)多云彈性混部。