01 背景
中大型互聯網公司的服務器數量可達萬級別,在降本增效的大背景下,機器資源利用率的重要性日益凸顯。如何在確保服務SLO影響最小的情況下提高機器資源利用率,從而降低服務器的采購成本,是一項非常值得研究的課題。
對于k8s云平臺來說,造成機器平均資源利用率低的原因可以概括為以下幾點:
業務申請的資源配額超過實際使用量。即用戶在申請資源時可能會對服務的真實資源使用情況估計不足,一般傾向于申請過量的資源。這就導致機器配額被占滿,無法繼續調度容器,而實際資源利用率卻很低。
服務的資源使用量存在波峰波谷。大部分服務的負載都會存在高低峰,當服務處于波谷的時候就會存在很大的資源浪費。
針對上述問題1),我們可以通過服務畫像給業務推薦一個合理的資源配置值,并結合彈性伸縮的手段來解決。
針對上述問題2),關鍵點在于如何將業務波谷時空閑出來的那部分資源利用起來,比如凌晨在線業務處于波谷的時候,往在線集群調度適量的離線任務。
目前B站私有云平臺已經達到較大的機器規模,我們從上述兩個思路出發來給整體云平臺降本:一方面提供了hpa和vpa的彈性伸縮能力,使得業務資源配額使用更為合理;另一方面,我們實施了較大規模的業務混部來解決算力的閑置問題。本文將主要分享B站云平臺的混部實踐,而彈性伸縮方面的實踐我們會擇機在后續文章中介紹。
02 混部的概念
我們把業務劃分為在線業務和離線業務。在線業務一般是各類微服務,特點是延時敏感、有很高的可用性要求,如推薦、廣告、搜索等服務;離線業務一般是批處理任務,特點是延時不敏感、允許出錯重跑,如大數據場景中的MapReduce任務、視頻處理中的轉碼任務等。所謂混部技術,就是通過調度、資源隔離等手段,將不同類型、不同優先級的在離線業務部署在相同的物理機器上,并且保證業務的SLO,最終達到提高資源利用率、降低成本的目的。需要注意的是,混部不是簡單地將容器部署到同一臺宿主機上,而是需要通過調度算法將混部任務調度到具有空閑資源的機器,同時需要有隔離機制來保證高優任務不會受到混部任務的干擾。
03 B站混部的場景
1. 在離線混部。B站是一個視頻類網站,存在大量的點播視頻轉碼任務,這類任務屬于計算密集型,具有運行時間短、允許失敗重試等特點。另外,在凌晨時段會觸發大量的轉碼定時任務,剛好和在線業務形成錯峰。我們通過在離線混部技術將轉碼任務調度到在線集群,既提高了在線集群的資源使用率,又補充了轉碼任務高峰期時的算力缺口,極大地降低了服務器成本。這類混部場景的難點在于:
調度層。(1) 混部任務不能影響在線任務的整體配額容量,例如機器一共64核,如果混部任務直接申請32核的cpu request資源,那就會造成該機器只能調度32c的在線業務容器。(2) 調度器需要動態感知到各個節點可混部資源量的變化,資源空閑越多的節點調度越多的混部任務。
節點層;觳咳蝿找坏┱{度到某個k8s節點后,在cpu、內存、磁盤、網絡等各個資源層面都有可能對在線任務產生“競爭”,因此需要隨時感知在線任務的負載情況并做相應的隔離管控,盡量做到對在線任務零干擾。

2. 離線間混部。離線集群整體的cpu使用率較高,但部分時段也存在一定的資源閑置,例如訓練平臺在訓練任務較少時整體利用率會偏低。由于都是離線任務,延時敏感性沒有在線那么高,因此這類場景除了混部轉碼任務外,還可以混部一些更“重”的大數據任務。但是大數據任務通常用yarn調度,如何將k8s調度和yarn調度進行協調是我們需要解決的關鍵問題。實現了大數據混部后,我們就可以做到各個離線業務互相出讓資源。例如將hdfs datanode機器接入k8s用于混部轉碼任務;反過來,轉碼的機器上也可以運行hadoop/spark等大數據任務。

3. 閑置機器混部。IDC通常會存在一定量的備機,用于各業務應急場景使用,但是日常是閑置的。這部分機器我們也會自動化接入k8s跑混部任務,當業務需要借調備機時再自動下線混部。
下面,我們結合在離線混部和離線間混部這兩個場景,具體介紹一下混部的關鍵技術點。
04 在離線混部
4.1 總體架構

任務提交模塊。caster是我們的在線業務發布平臺,crm則是離線批處理任務提交平臺。crm可以支持多集群調度、混部資源余量統計、混部資源quota管控等。
k8s調度模塊。kube-scheduler為原生的在線任務調度器,而job-scheduler是我們自研的離線任務調度器,能支持轉碼任務的高并發調度。另外webhook負責對離線任務的資源配額進行動態轉換,轉換為自定義的k8s擴展資源。
colocation-agent。每個k8s節點上都會部署混部agent,負責混部算力動態計算和上報、資源隔離、監控數據上報等。
colocation config manager。在大規模k8s集群中,各類節點的混部配置存在一定的差異性,同時也存在動態更新的需求。該模塊負責對混部配置進行集中管控,支持策略下發、開關混部等功能。
混部的可觀測性。每個節點的agent負責采集節點中的一些混部指標,例如:可混部資源量、實際的混部資源用量等,最終上報給prometheus進行看板展示?捎^測性對于排查單機的混部問題非常有用,我們可以很方便地通過監控曲線來查看某個時刻的混部資源使用情況。同時,我們也可以隨時查看整體集群的混部算力使用趨勢。
下面,我們從混部任務調度、在線QoS保障兩方面來介紹在離線混部的關鍵技術點。
4.2 混部任務調度
k8s原生調度器的基本原理和問題
k8s的每個節點都會上報節點資源總量(例如allocatable cpu)。對于一個待調度的pod,k8s調度器會查看pod的資源請求配額(例如cpu reqeust)以及相關調度約束,然后經過預選和優選階段,最終挑選出一個最佳的node用于部署該pod。如果混部任務直接使用這套原生的調度機制會存在幾個問題:
混部pod會占用原生的資源配額(例如cpu request),這會導致在線任務發布的時候沒有可用資源;
原生調度本質是靜態調度,沒有考慮機器實際負載,因此沒法有效地將混部任務調度到實際負載有空閑的機器上。
基于擴展資源的混部調度

為了解決上述問題,我們基于k8s的擴展資源進行混部任務調度,整體分為3個步驟:
1. colocation agent模塊中,策略組件會實時加載當前接收到的混部配置,并調用autopilot組件進行混部算力的計算,然后通過device-plugin組件上報混部擴展資源,例如caster.io/colocation-cpu
2. 混部任務在申請資源配額時,仍然申請原生cpu資源,但是會增加pod標簽“caster.io/resource-type: colocation”。k8s webhook模塊根據標簽識別到混部pod,然后將pod申請的資源修改為混部擴展資源。這種方式對業務層屏蔽了底層擴展資源,通過標注pod標簽即可指定是否使用混部資源。

3. 混部調度器job-scheduler根據pod申請的擴展資源量以及各個節點上報的混部擴展資源量進行調度。我們利用轉碼pod存在同質化(資源規格和調度約束相同)的特點對調度器進行了優化,基本思路是:
將pod與調度相關的字段進行hash值計算,并在調度隊列中按hash值排序pod
pod預選的結果同樣也滿足其他同質化pod的要求,因此將預選node進行緩存
當前處理的pod若是同質化pod,則從緩存中直接選取一個節點進行調度
混部資源量計算
k8s node是怎么確定當前節點應該上報多少混部擴展資源量的呢?我們針對不同的應用場景設計了不同的混部策略算法:
1. 動態計算。針對各類物理資源,例如cpu、memory等,我們會分別設置機器的安全水位值n%。agent會實時探測在線進程的資源使用量online_usage,然后根據安全水位和在線負載動態計算出可混部資源量。在線使用量和可混部資源量是此消彼長的,隨著在線使用量上升,我們上報的可混部量就會下降,反之,當在線使用量下降,可混部量就會上升。

2. 靜態計算。例如備機池閑置機器沒有在線業務,不需要動態資源計算,因此我們可以配置靜態上報策略,上報固定的可混部資源量即可。
3. 分時計算。如果部分在線業務在某些時間段不希望部署混部任務,我們就需要用到分時策略,即在某些時間段關閉混部或者減少上報混部資源量。另外,我們還支持設置grace period,在分時混部結束前,會提前停止調度混部任務到該k8s node,并等待存量任務結束,做到優雅退出。
4.3 在線QoS保障
資源隔離是混部架構的關鍵難點。我們希望在提高單機混部資源量的同時,盡可能地降低混部任務對在線業務的性能影響。主要從三個層次來保障在線業務的QoS:
任務調度。根據前文所述的混部任務調度機制,混部調度器可以實時感知各節點的可混部資源量,因此可以從全局視角將混部任務調度到資源充足的節點上。
資源隔離。節點混部agent可以秒級檢測在線負載變化,根據安全水位值計算當前可混部資源量,然后通過cgroup及時進行資源限制。
任務驅逐。離線的混部任務一般都是可重試的,因此驅逐可以作為一種兜底手段。
下面我們詳細介紹一下資源隔離層的幾種策略。
混部大框
在前面的介紹中我們提到webhook會對混部任務申請的資源類型進行修改,去除原生的資源類型request.cpu和request.memory,改成caster.io/colocation-cpu和caster.io/colocation-memory。由于沒有申請原生資源類型,那么k8s會自動將這類pod歸類為best effort類型,并且最終通過runc將該類pod的cgroup設置到/sys/fs/cgroup/cpu/kubepods/besteffort目錄,我們稱為“混部大框”。

cpu動態隔離
在cgroup層面,我們給大框設置了最小的cpu share值,保證在資源爭搶時,混部任務獲得cpu時間片的權重最小。
colocation agent中的cgroup manager組件負責動態地調整“混部大框”的cpu quota,從而對混部任務進行整體的資源限制。當colocation agent檢測到在線負載降低時,就會調大“混部大框”的cpu quota,讓混部任務充分利用空閑的算力。當在線負載升高時,則是縮小“混部大框”的cpu quota,快速讓出資源給在線業務使用。
此外,我們通過cpuset cgroup對整體混部大框做了綁核處理,避免混部任務進程頻繁切換干擾在線業務進程。當混部算力改變時,agent會給大框動態選取相應的cpu核心進行綁定。另外,選取cpu核心的時候也考慮了cpu HT,即盡量將同一個物理核上的邏輯核同時綁定給混部任務使用。否則,如果在線任務和混部任務分別跑在一個物理核的兩個邏輯核上,在線任務還是有可能受到“noisy neighbor”干擾。
內存動態隔離
與cpu隔離方式類似,colocation agent會根據當前在線業務內存使用情況,動態擴縮混部大框的memory quota。另外,通過調節oom_score_adj,混部任務的oom_sore被設為最大值,保證oom時混部任務盡量優先被驅逐。
網絡帶寬限制
我們使用了cni-adaptor組件,使得k8s node可以支持多種網絡模式,對于轉碼混部任務,通常不需要被外部訪問,因此通過annotation可以指定bridge網絡模式,分配host-local的ip,避免占用全局網段中的ip資源。同時也利用了linux tc進行混部pod的網絡帶寬限制。
驅逐機制
混部agent層支持內存、磁盤、cpu load等維度的驅逐機制。當任意資源負載達到設置的驅逐水位時,agent會立即驅逐機器上的混部任務。為了防止任務在同一臺機器上被頻繁驅逐,需要在驅逐后設置一定的冷卻時間,冷卻期內禁止調度混部任務。
05 離線間混部
針對訓練、轉碼等離線集群跑大數據混部任務的場景,我們基于在離線混部框架做了功能增強,其關鍵點在于yarn nodemanager on k8s。具體的調度步驟為:

yarn node manager以daemonset的形式部署在相應的混部節點上
節點上的混部agent會動態檢測在線容器負載變化,并根據設置的混部策略計算可混部值。這個值一方面會通過接口上報給yarn rm,另外一方面會設置到混部大框的cgroup中進行動態的資源限制
用戶把大數據任務提交到混部集群時,rm會找到集群中有充足資源的混部節點,并最終在nm中拉起task
為了降低大數據任務對非混部業務的影響,大數據團隊也做了相關技術改造,例如支持remote shuffle、基于應用畫像識別小規格任務進行調度等。
06 混部管理平臺
我們開發了界面化的混部管理平臺來支撐日常的運維需求。主要功能包括:
策略管理。支持批量查看和設置節點的混部策略,例如安全水位、硬限值等。同時也支持設置節點組,只要節點打上對應的組標簽,管控層可以秒級感知并立即下發相應混部策略。
開關混部。如果臨時需要對特定機器關閉混部,可以在平臺進行一鍵關閉,此時會立即驅逐機器上的混部任務并且停止上報混部資源。
監控查看。單機粒度監控主要滿足日常排障需求,可以精確查看某一時刻機器上的混部上報量、混部任務數、混部實際資源消耗等。節點組粒度的監控則可以評估這批機器整體貢獻的混部量以及對應的使用情況。


07 混部效果
目前B站云平臺大部分機器都參與了混部,混部機器的平均cpu使用率可以達到35%,峰值使用率則可以達到55%左右。這些混部算力支撐了B站大規模的視頻轉碼任務,以及ai機審、大數據MR等任務,節省了數千臺機器的采購成本。
08 總結
本文介紹了B站基于k8s云平臺進行的混部實踐,主要分為在離線混部、離線間混部等業務場景。我們采用了一套對k8s無侵入的混部框架,并且通過調度、資源隔離等手段來確保非混部業務的SLO,另外也開發了相關的監控、策略管理平臺等來提高整體混部系統的可運維性。后續我們會在內核層隔離與可觀測、統一調度等方面優化混部技術框架,持續助力云平臺降本。
文章內容僅供閱讀,不構成投資建議,請謹慎對待。投資者據此操作,風險自擔。
海報生成中...
海藝AI的模型系統在國際市場上廣受好評,目前站內累計模型數超過80萬個,涵蓋寫實、二次元、插畫、設計、攝影、風格化圖像等多類型應用場景,基本覆蓋所有主流創作風格。
IDC今日發布的《全球智能家居清潔機器人設備市場季度跟蹤報告,2025年第二季度》顯示,上半年全球智能家居清潔機器人市場出貨1,2萬臺,同比增長33%,顯示出品類強勁的市場需求。