位元組跳動基於大規模彈性伸縮實現拓撲感知的在離線並池

語言: CN / TW / HK

 1. 專案背景

節跳動的業務型別具備多元化的特點,主要包括線上業務體系和離線業務體系。

  • 線上業務體系:通常服務於終端使用者,包含 Web 服務,演算法服務,有狀態服務,影片編解碼、FaaS 服務等,這些服務通常對 RPC 呼叫延遲比較敏感。
  • 離線業務體系:包含臨時查詢、定時報表、模型訓練、資料分析等作業,這些服務的特點是它們可以承受一定程度的排隊或等待,在合理時間得到合理結果即可。

為了保證線上業務的穩定性,研發團隊會將大量計算資源供給線上業務體系。這會導致離線作業處於較為嚴重的排隊狀態,而線上業務體系自身會呈現比較明顯的潮汐效應。

下圖展示了位元組內部的線上業務和離線業務的天級 CPU 利用率情況。從圖中可以看到,離線業務基本可以在天級維度將 CPU 利用率維持在較高水平;而線上業務晚高峰的整體 CPU 利用率可能只達到峰值的 20% ~ 30%,造成離線業務排隊和資源浪費的問題。

為了更好地解決資源匹配問題,業界的常用做法是通過在離線資源並池實現利用率的提升,位元組跳動內部也採用了類似的方式。根據統計,位元組內部資源佔用最多的線上業務主要是 Web 服務和演算法類服務;排隊最嚴重的離線業務主要是報表查詢和模型訓練相關的作業。

因此,位元組內部研發團隊的優化重點是針對這些不同的業務型別,定製不同的並池方案,主要有以下 2 種資源效率提升場景。

1.1 場景一:線上 Web 服務和離線批式作業

研發團隊首先選擇進行並池的服務是線上 Web 服務和離線批式作業。為什麼選擇這兩種服務,主要是考慮到它們的業務模型簡單,且資源模型互補。

  • 線上 Web 服務:由於位元組的微服務架構大多基於 Golang 進行編寫,線上 Web 服務在資源使用模式上更加偏向於 CPU,較少佔用記憶體、磁碟、網路等資源,因此線上 Web 服務天然適合與離線報表查詢的批式作業進行混合部署。
  • 離線批式作業:批式執行時間短,存在快進快出的特性,同時十分消耗記憶體和吞吐,在資源模式上可以與線上 Web 服務形成匹配;同時,離線作業在執行過程中並不重延時,當線上服務出現 Burst 行為時,我們可以在單機維度對離線作業進行資源擠壓,甚至殺死異常例項。

因此研發團隊採取了在離線混合部署方案,通過單機多維度的資源隔離以及中心 + 節點兩級管控的策略,很好地支援了兩種服務進行並池嘗試。

 1.2 場景二:線上演算法服務和離線訓練作業

為什麼選擇這兩種服務?主要是考慮到它們的業務模型複雜,且資源模型同質。

  • 線上演算法服務:包括推薦、廣告、搜尋核心服務等;演算法服務在運營過程中需要載入大量的線上模型,在資源使用上除了佔用 CPU,也會佔用較大的記憶體;同時演算法服務不僅對呼叫延遲較為敏感,對業務的展現效果也有一定要求;為了滿足服務的極致效能要求,我們通常需要對服務進行一些 NUMA 繫結,或者使用 GPU、RDMA 等異構裝置支援達到交付效果。
  • 離線訓練作業:包括推薦廣告 CTR/CVR、NLP訓練等;該類服務在訓練過程中需要注重吞吐和效果,如果對其進行資源擠壓,將無法保證訓練的效果是否穩定復現;同時訓練作業執行時間長,且需要多個不同的訓練角色協調互動才能夠完整執行一個業務;為了滿足訓練作業的高質量資源要求,我們也會提供 NUMA 繫結和異構裝置支援。

因此,面對這類資源並池場景,位元組研發團隊採取了彈性並池方案,即在線上業務低峰的時段將線上資源進行縮容,騰出空閒的資源供給離線業務使用,從而實現資源的分享複用,提高資源利用效率。

 1.3 彈性並池挑戰

為了保證彈性並池方案的順利落地,此處有三點值得考慮:如何彈、如何用、如何穩。

  • 如何彈:線上業務容器化改造後,天然支援水平擴充套件,但是離線服務會有一些比較複雜的編排框架,因此我們需要對離線的業務體系提供一些深度的結合與定製,增強彈效能力。
  • 如何用:線上業務和離線業務作為兩套不同的業務體系,甚至可能部署在兩個不同的叢集,因此如何實現跨資源的協同感知也是一個重要的問題。
  • 如何穩:彈性資源最大的特點是它整體的資源供應量不確定,當線上服務出現抖動時,我們需要優先保證線上服務的穩定性,極端情況下會做容器兜底殺死的邏輯,而這會與保證離線業務的穩定性背道而馳,因此如何在不穩定的資源供應基礎上保證離線業務的穩定性也十分重要。

2. 在離線彈性體系

針對上述彈性並池挑戰,下文將分別從線上彈性設計、離線式分佈訓練、在離線資源協同感知和穩定性保證四個方面提出解決方案。

 2.1 線上彈性設計

線上服務天然支援水平擴充套件,關鍵挑戰在於構建快、穩的彈性系統。為了應對該挑戰,先來看一看線上彈性分層架構,如下圖所示:

從圖中可以看到,Agent 負責採集業務各種資料,包括業務指標如 QPS 、P99 延遲等,以及系統維度指標如  Load、CPU 利用率等。這些資料最終會由兩個接收方進行消費,一方面它會通過中心式採集的元件進入到實時資料的儲存系統,另一方面它會通過一個訊息佇列進入離線演算法模型中。

中心式的 Controller 負責消費這兩種資料,並在這些資料的基礎上決定當前的擴縮容行為。需要補充一點,位元組內部研發團隊沒有使用原生的 Deployment 描述線上的無狀態服務,而是在上面構建了一層 HPAGroup 用於控制多個 Deployment 支援小流量或者 AB 釋出。因此擴縮容行為是由 Controller 調整 HPAGroup 的 replica 數,最終進入到 K8s 排程體系中產生 Pod,完成最終的排程。

2.1.1 在線彈性實時性保證

如何實現整個彈性系統"快"的特性要求,研發團隊在實時性保證方面進行了三方面的優化,以達到“非突發流量預先擴容,突發流量分鐘級擴容”的效果。

一是模型觸發:發團隊建構了一個模型觸發機制,可以基於業務的歷史資料構建資源畫像,從而取得業務流量。在沒有發生異常突發的階段,可以提前預測執行擴容行為。

二是實時觸發:研發團隊自研了可擴充套件記憶體資料儲存系統,同時根據位元組內部的服務組織方式,在記憶體中建立了多級維度索引,加快查詢效率。同時我們通過實時資料預取,以及聚合邏輯下發的方式,加快整個資料獲取的速度。

三是元件效能:在整個擴容鏈路中消耗時間較大的主要有三個方面:K8s 雲原生排程器的效能、映象拉取的效能、推廣、搜尋核心服務。針對這三種場景,我們首先通過分片排程 + 樂觀併發 Bind 的方式來加速我們排程器的吞吐和效能,其次通過映象 Lazy Loading 進行按需載入,最後自研 P2P 實現映象和模型快速分發。

2.1.2 線上彈性穩定性保證

如何實現整個彈性系統"穩"的特性要求,研發團隊進行了以下 6 個方面的優化。

配額:縮容部分資源仍然佔住配額,服務可以隨時可回收;

資料:系統指標和業務指標協同,完善資料異常 fallback 機制;

元件:分散式追蹤 Pod 生命週期,完善報警,快速定位元件異常;

聯邦:叢集具備自治能力,聯邦提供自動故障切換;

組合:根據呼叫關係提供鏈路組擴縮能力,避免出現服務瓶頸;

兜底:在縮容業務例項時,並沒有真正刪除容器,而是建立一個 Shadow Deployment 通過上層流量摘除以及啟動程序替換實現容器的保留。當出現一些異常情況時,我們可以快速地重新拉取流量,從而實現一鍵式容災,如下圖所示:

 2.2 離線分散式訓練

離線分散式訓練模型根據通訊模式的不同,主要分為兩種模式:PS-Worker 框架和 Ring AllReduce 框架。

2.2.1 PS-Worker 彈性定製

下圖展示了 PS-Worker 離線分散式訓練框架:

在 PS-Worker 訓練框架中,所有業務例項大致分為兩種角色:PS 和 Worker。其中,PS 負責儲存整個分散式訓練的引數,其本身需要保證相對的穩定,不具備彈效能力;Worker 負責實時地從 PS 裡面拉取當前模型引數,並從 HDFS 中讀取模訓練的資料輸入,將訓練完成的梯度的資訊更新到對應的 PS 中。

由於在該場景下,PS 本身不具備任何彈效能力,且 Worker 彈性加速比其實不高,因此為了應對該場景下的彈性資源使用問題,我們通常會將整個訓練作業作為一個維度來進行彈性擴縮。

2.2.2 Ring AllReduce 彈性定製

下圖展示了 Ring AllReduce 離線分散式訓練框架:

在該訓練框架中不存在中心式節點,所有的節點都是 Worker,即所有的節點都可以參與梯度計算過程。整個訓練過程會分為若干個 Step,在每個 Step 中,每個 Worker 都會獲取一份獨立的資料,並且每個 Worker 都會載入當前的模型引數,然後獨立地去計算自己的引數梯度。

除此之外,Worker 之間是有序的,每個 Worker 在計算完當前 Step 的梯度之後,會找到自己的下一跳, 然後把自己計算的梯度傳遞給它。一輪 Step 訓練最多可以經過 2N-1 次的引數傳遞和收斂,從而完成一輪所有梯度在全 Worker 的傳播。此時 Worker 就有了完整的梯度資訊,隨後可以開始下一次 Step 操作。

Ring AllReduce 訓練框架中,Woker 天然支援故障容忍和彈性,且彈性加速比很大,彈性加速的效果和 Worker 的數量呈現出正向比例關係,問題在於 Worker 之間存在非常明顯的木桶效應,因此我們需要儘可能地保持不同 Worker 的資源是同質的。在該場景中,我們一般以單 Pod 的維度作為一個彈性的最小粒度來進行彈性擴縮。

 2.3 在離線資源協同感知

為了實現在離線資源資源之間的協同感知,我們主要進行了兩個方向的工作:單叢集統一排程和跨叢集資源整合。

2.3.1單叢集統一資源排程

在離線並池的前提是構建統一的單叢集排程和管控體系,研發團隊主要進行了以下三個方面的工作:

自定義 CRD 擴充套件資源表達:K8s 原生擁有一個 Node 物件進行資源儲存, 但是該物件的資源表達能力非常弱,只能儲存一些簡單的資料資訊。但是由於位元組場景需要很多異構裝置支援,並且需要 NUMA 維度的拓撲表達。因此研發團隊自定義了一個 CRD 擴充套件資源表達能力。

微拓撲感知排程:位元組研發團隊自研了一套在離線統一的排程系統,支援 Gang/Same 等豐富的排程語義,另外基於 Schedule Framework 去做了很多定製化的 Predicate 和 Priority 的策略改造,並且儘可能地去堆疊 NUMA 來減少資源的浪費等。

微拓撲感知管控:位元組研發團隊使用了社群原生的 Toplogy Manager 來實現拓撲的分配和管理。並且將社群原生的 CPU Manager 或者 Memory Manager 下沉到 Plugin 中實現,同時抽象了一層和 Device Manager 同級的 Resource Manager 。

2.3.2 跨叢集資源整合

為了解決跨叢集資源整合的問題,位元組研發團隊引入了社群的 Virtual Kubelet 方案,在離線的叢集中插入了若干個虛擬節點,由虛擬節點彙總某一個線上叢集裡面的彈性資源資訊,從而實現跨叢集的資源整合。

引入虛擬節點也帶來了一個新的問題,即 Gang/Same 語義實現起來會比較複雜。為了解決該問題,我們執行了一個比較簡單的約束——對於一個相同的作業,它所有的 Pod 如果需要去使用彈性資源,當前只能通過一個虛擬節點同步到同一個後端叢集,由此可以把整個微拓撲或者排程的難度重新 Upload 到單叢集的視角進行解決。目前的方式是在後端實現 Same 和拓撲感知的語義,在前端保證 Gang 的語義。

 2.4 穩定性保證

至此本文已經解決了線上業務和離線業務“怎麼彈”、“如何用”的問題,但我們還面臨最後一個問題,即如何在看似不穩定的資源裡面為離線業務提供穩定性的保證。資源不穩定性來源於多方面,主要有以下三種:

首先,整體資源的供應是不穩定的,因為整個資源的供應量是完全受制於線上業務的擴縮容情況,這會導致整體的資源的總量、資源供應的時間,甚至每一天資源所對應的具體的機器環境是不一樣的。因此我們沒有辦法讓離線業務針對彈性資源做一些提前的資源規劃,同時當線上業務發生任何抖動時,我們會隨時產生資源回收,這對整個訓練作業的體驗並不好。

其次,單個作業記憶體在 Min/Max 語義,即 Worker 的數量其實是不確定的,離線業務整體的資源描述也並非確定值。同時我們還需要解決一個問題,即在提高單個作業的訓練速度和滿足更多訓練作業之尋求平衡。

最後,由於 Gang/Same 語義的存在,資源排程的過程中可能會出現資源死鎖情況,即每一個作業都拿到了一部分資源,但這部分資源不足以支撐它執行,由此資源死鎖導致資源浪費。

位元組內部如何解決上述問題?

  • 在資源供應方面:我們在執行縮容操作的過程中,引入了 Deletion Cost 機制定義例項縮容的優先順序。比如我們可以儘可能地縮容整機或者整 Socket,甚至儘可能地保證這些縮容出來的資源處於同一個 Pod 或者使用了同質的 GPU ,從而減少資源碎片的問題。
  • 在資源分配與排程方面:一方面,位元組研發團隊採用的策略是優先滿足單個作業的加速比需求。因為作業在排程和非排程的過程中,可能會執行很多次 Checkpoint Dump 和 Reload 操作,這個操作過程需要從 HDFS 上實現完整模型的上傳和下載,非常耗時。如果我們執行更多的作業,雖然在一定程度上可以優化使用者的體驗,但是會觸發多次無效的 Checkpoint 操作佔據大量時間,從而降低資源的利用效率。另一方面,為了解決資源死鎖問題,我們在 Gang 語義的基礎上加了一個隨機超時機制,即在排程器中,如果我們發現一個 Gang 語義持續了一段時間仍然不能滿足,我們會先執行一段隨機的休眠,然後回滾排程狀態,讓其他作業能夠重新再來一次 Gang 過程,避免資源死鎖。
  • 在資源回收方面:為了解決資源回收的過程中無腦地殺死離線業務的問題,位元組研發團隊構建了彈性資源的優先順序,基於優先順序實現資源回收。目前的彈性資源大概分為三級,如下圖所示。以 PS-Worker 架構為例,PS 作業可能會處於一個 High 的優先順序;能夠滿足基本執行的 Min 的 Worker 處於中優的優先順序;為了進行彈性加測的 Worker 處於 Low 的優先順序。這樣做的好處是當我們線上進行資源回收時,我們可以定製一些排程器的搶佔策略,使得線上服務總是傾向於去搶佔低優先順序的作業資源。

  2.5 彈性並池體系總結

基於以上彈性方案實現在離線並池的整體架構圖,如下圖所示:

首先,線上叢集裡面存在著多個 K8s 叢集,然後在上一層抽象一個統一的叢集聯邦,通過 Federation 和 Member Cluster 兩級的叢集建設,構建了一套線上內部實時且穩定的彈性系統,從而解決線上業務能夠被彈起來的問題。然後在單個離線叢集內部,我們通過和離線的框架進行深度的融合,從而解決了離線能夠被彈起來的問題。

其次,為了解決資源的協同感知,我們通過引入虛擬節點,從而實現了跨叢集的資源整合。同時在單個叢集中,我們通過一體化排程和一體化單機維度的資源管控能力,從而很好地解決拓撲感知的排程和管控能力。

最後,為了解決離線資源使用體驗問題,我們定製化了縮容策略、資源分配策略、優先順序建設,從而使得離線業務雖然使用的不是穩定的資源,但也有一定的穩定性保證。

 3. 案例分析

基於上述彈性並池體系,下文將分享三種彈性資源並池場景案例。

3.1 Ring AllReduce 使用彈性資源

場景一是 NLP 和線上推理服務進行資源並池。通常來說, NLP 場景更適合使用 Ring AllReduce 的訓練方案。我們可以在一個 GPU 的視訊記憶體裡完整地載入所有的模型引數,通過 Ring AllReduce 更加合理地使用整體頻寬,從而達到較高的加速比。

框架說明:在具體實現中,位元組研發團隊基於社群的 Horovod 和 Et-operator 實現了 Ring AllReduce 框架彈性。從上圖可以看到,框架引入了一箇中心式 Launcher 負責 Worker 之間通訊環建立、Worker 健康狀態檢查、異常處理等邏輯。

該場景的彈性思路:將 Launcher 和滿足基本訓練需要的 Worker 執行在穩定資源上,同時將用於加速的彈性 Worker 執行在彈性資源上。線上推理模型通常來說比較大,一個推理模型的例項可能會佔據一個整機,因此這種做法的好處是:縮容一個線上例項等於縮容一臺機器,從而供給完整的機器給 Ring AllReduce 的 Worker 執行,規避單機硬體資源的隔離問題。

目前整套框架的彈性加速比可以達到 1:8 水平,達到了對彈性資源充分利用的效果。

 3.2 PS-Worker 使用彈性資源

場景二是 PS-Worker 和推廣搜核心服務共用 CPU 和 GPU 資源的情形。通常來說,CTV/CVR 的訓練模型非常稀疏,而且特徵維度非常龐大,所以單機基本沒有辦法裝上所有的特徵引數,因此這類訓練模式基本上只能使用 PS-Worker 架構。位元組內部對 CTV/CVR 這種訓練模型的需求十分大,為了更好地支援這種訓練任務,位元組內部自研了一套 PS-Worker 框架進行非同步訓練。

與傳統 PS-Worker 不同的是,自研框架中的 Worker 被拆分為 Sparse 部分和 Dense 部分。其中 Dense 部分主要負責稠密模型的訓練,它能在一個完整的 GPU 卡上載入所有模型引數,從而實現更好的加速效果;而 Sparse 和 PS 通常執行在廉價的 CPU 上。

同時, PS、Worker、線上三種服務會可能同時執行在一臺機器上,共享部分單機資源,需要我們提供一些隔離機制減少互相干擾。例如,我們採用雙網絡卡方案,在單機上進行分流,在交換機側通過流量優先順序打標的方式保證線上穩定性;在 NUMA 分配策略上通過微拓撲感知的能力,針對不同的角色定製 NUMA 分配邏輯。

另外,PS-Worker 的彈性粒度是作業整體維度,不可避免會造成比較大的資源碎片,為了解決該問題,我們引入了影片編解碼或者 Spark 的一些 batch 類作業來填充資源碎片。

目前,這套框架在位元組內部得到了廣泛使用,每天可以出讓大概 300 萬核心乘以 7 小時的資源。

 3.3 線上服務使用彈性資源

最後,線上服務也會使用彈性資源,主要分為以下兩種場景:

一是節日或者促銷類的活動場景:該場景的特點是資源需求規模非常龐大,但可以提前規劃和容量預估。因此對於這種模式,位元組目前使用的方式是 CronHPA + 分時 Quota 預先分配配額。

二是直播場景:該場景可能需要載入一些新的模型,從而需求更多資源以獲取更多的展現效果上的正向收益。對於這種臨時需要突破自己容量的情況,我們會允許它突破自己的 Quota 上限,使用低優的離線叢集的資源來滿足自己的臨時性的需求。為了使得整個機制更加合理,我們會對低優的離線叢集資源的水位進行實時監控,從而確保離線叢集的資源不會被壓榨得過於厲害,同時去保證離線服務總是會有一定的 Buffer 來承擔線上服務異常流量增長情況。

4. 未來展望

關於未來展望,主要有以下三個方向:

規模化

  • 線上服務彈性規模和時間擴充套件;

  • 離線作業雲原生和彈性化改造;

  • 在離線一體化聯邦建設,收斂在離線整個作業的提交入口。

產品化

  • 彈性容器產品能力完善:目前位元組內部彈性資源和穩定資源的使用方式相對割裂,產品能力上有一些不足,因此後續研發團隊會完善相關的能力;

  • 視覺化資源檢視和容量統計。

精細化

  • 精細化排程,減少資源碎片;

  • 叢集維度資源切分到全面整合,形成統一的資源池。​​​​​​​

更多資訊