Serverless:基於個性化服務畫像的彈性伸縮實踐

語言: CN / TW / HK

作者 | zzbtie

導讀

雲原生環境下業務大規模迭代的成本壓力日益增大。我們以Serverless理念為指導,針對百度Feed的後端服務,從彈性、流量、容量角度構建多維度個性化服務畫像,並基於畫像對服務進行彈性伸縮,隨流量波動自適應調整服務容量,有效地降低業務執行成本,本文重點介紹上述相關策略與實踐方案。

全文6542字,預計閱讀時間17分鐘。

01 背景

隨著雲原生在百度內部各產品線的推進,微服務已成為各業務線的標配,在搜尋、推薦、廣告這類重策略計算業務場景中,後端通常由很多微服務組成,這些微服務普遍存在如下特點:

  • 例項多:每個服務由多個例項組成,微服務間通過rpc通訊,服務一般支援橫向/縱向擴縮容。

  • 計算重:微服務包含比較複雜的業務邏輯,通常服務本地會載入一些策略詞典進行復雜的策略計算,服務本身需要的cpu等資源比較多。

  • 7*24h:服務通常使用固定的容量提供7*24h線上服務,並且由雲原生元件進行定期的容量治理,例如冗餘容量回收等。

百度App推薦服務(簡稱百度Feed)作為典型的推薦業務場景,後端包含眾多策略複雜、重計算的微服務,這些後端服務普遍使用固定的容量為數億級使用者提供7*24h的資訊流推薦服務。對於百度Feed的後端服務而言,使用者流量存在著典型的波峰浪谷現象,而在流量低谷期和高峰期使用相同的容量無疑存在資源浪費,本文介紹百度Feed在後端服務進行Serverless的實踐,詳細說明基於服務畫像的彈性伸縮相關技術方案與實現。

02 思路與目標

業界對Serverless的大規模實踐在FaaS側比較多,通常例項較輕量,容器的生命週期也比較短。而我們面對的是比較“重”的後端服務,這類服務的例項擴容通常包括以下幾個階段:

  • PaaS初始化容器:PaaS根據例項的quota需求(cpu、記憶體、磁碟等)尋找合適的機器分配容器,並初始化容器。

  • 二進位制檔案與詞典檔案準備:將服務的二進位制檔案和詞典檔案從遠端下載到本地,並進行解壓。

  • 例項啟動:例項在本地根據啟動指令碼啟動程序,並將例項資訊註冊到服務發現。

後端服務例項擴容的時間通常在分鐘級,而詞典檔案的下載與解壓一般佔整體擴容時間70%以上,對於詞典較大的例項則耗時更多,這導致後端服務面對流量變化時無法在極短的時間內(例如秒級)進行伸縮來保障容量穩定。然而這些後端服務的流量通常是週期性地波動,具有明顯的潮汐特徵,如果我們能對服務的流量進行較為準確的預測,那麼面對流量的上漲我們可以適當地提前擴容來保障容量,面對流量下降可以進行一定的縮容來節省資源成本,實現資源按需使用。

整體而言,我們以雲原生元件為基礎,為每個服務刻畫出多維度的個性化服務畫像,包括彈性維度、容量維度、流量維度,在保障服務穩定性的前提下實現服務容量隨流量波動的自適應調整。實現效果如下圖所示,左圖中常態方式下一個服務消耗的資源量是固定的不隨著流量波動而變化(資源量需滿足峰值流量所需的容量),右圖中Serverless模式下服務消耗的資源量隨流量波動而動態調整。

03 整體架構

整體的彈性伸縮架構如下圖:

  • 服務畫像:包括彈性畫像、流量畫像和容量畫像,多維度刻畫了服務的個性化特徵。

  • 彈性策略:應對不同場景下的伸縮策略,包括預測彈性、負載反饋彈性和定時彈性,是實現Serverless的基礎核心策略。

  • 雲原生元件:包括PaaS和ALM(app lifecycle managent),其中PaaS負責執行服務的伸縮動作,ALM負責管理所有涉及服務的資料和策略。

  • 資源:包括集團雲和公有云兩類彈性資源,Serverless支援兩類雲資源相關的服務伸縮。

  • 穩定性保障:為彈性伸縮穩定性保駕護航的各類機制,包括彈性巡檢、容量巡檢、狀態巡檢和一鍵干預等。

  • 伸縮平臺:實現整體策略的支援平臺,包括資源預查、流程編排、狀態輪轉和事件引擎等基礎機制。

接下來分別介紹核心的策略和實踐,包括服務畫像、彈性策略、穩定性保障。

04 服務畫像

百度Feed後端包含眾多服務,各服務的詞典檔案大小不同,有些服務的cpu計算比較多,有些則io比較多,各服務在可伸縮性、流量波動情況和負載能力都存在差異。因此我們圍繞服務的線上執行資料,從彈性維度、流量維度和負載維度構建個性化的彈性畫像、流量畫像和容量畫像,多維度刻畫出每個服務的個性化特點。

4.1 彈性畫像

目標:從可伸縮角度刻畫服務的伸縮能力。根據雲原生指標、服務例項規格、例項部署遷移時間、資源依賴等維度刻畫服務的彈效能力,將業務內各服務劃分為如下三類:

高彈效能力:完全無狀態服務,可隨意無損伸縮,伸縮速度較快。

中彈效能力:有一定伸縮能力,但需要較長時間恢復服務狀態,伸縮速度一般。

低彈效能力:幾乎無伸縮能力,需要較大的代價恢復服務狀態,伸縮速度較差。

彈性畫像構建

對各服務從PaaS拿到多條最近例項擴容記錄獲取例項擴容時間,取中位數作為該服務的例項部署時間,結合該服務的例項quota(cpu、memory、磁碟),是否有狀態,是否存在外部依賴,通過簡單的規則將所有服務劃分為高、中、低彈效能力;同時我們推動服務進行標準化容器改造和存算分離來提升服務彈性。

彈效能力提升

  • 標準化容器改造:之前百度Feed業務內大部分服務例項都是非標準化容器,在埠隔離、資源混部方面存在缺陷,無法支援存算分離,影響服務的整體部署遷移效率;通過推進服務標準化容器改造,各服務已支援跨資源池、跨雲排程部署,可充分利用各資源池的碎片化資源,提升了資源交付效率與混部能力,有效改善服務的彈性伸縮能力

  • 存算分離:對於詞典檔案較大的後端服務,服務擴容的耗時集中在詞典檔案的下載與解壓,我們推動該類服務接入雲盤共享卷,服務例項部署時可遠端讀取詞典內容載入到記憶體中,減少詞典檔案的下載和解壓耗時,顯著提升了服務的部署和例項遷移時間,有效提升了服務的彈性伸縮能力

4.2 流量畫像

目標:

刻畫服務的流量變化趨勢,預測未來某個時間的流量進而方便根據流量配置對應的容量。

流量畫像構建:

  • cpu使用量:雖然流量畫像是根據歷史流量資料來預測未來流量資料,但是我們不直接採集qps資料,而是使用cpu使用量來代替qps。主要原因是後端服務通常有多個rpc/http介面,不同服務的介面數量不同,而且一個服務內的不同介面的qps、效能存在差異,而單一介面的qps指標無法反應服務整體的資源消耗,這導致使用多介面qps資料和服務的資源消耗之間建立對映存在困難。後端服務主要的資源開銷是cpu,而服務的cpu使用量是每個服務的單一通用指標,它直接反應了該服務在處理多介面請求時的整體資源開銷,因此該指標相比qps能更直接的刻畫出服務的容量需求。

  • 時間片:後端服務的流量普遍呈24小時週期性波動,我們將一天24小時劃分為多個時間片;對於每個服務,我們統計它的歷史資料(例如過去N天在每個時間片對應的流量資料)並根據歷史資料來預測未來某個時間片的流量情況。例如將24小時劃分為24個時間片,每個時間片對應1個小時,我們想預測某個服務在下午2點~3點對應時間片內的流量情況,那麼根據過去7天(N=7)該服務在下午2點~3點的流量資料來進行預測。其中,時間片的大小可配置,時間片配置的越小則對應時間範圍越小,對於流量在單位時間變化較大的服務可配置較小的時間片,而流量波動較小的服務可配置較大的時間片。

  • 監控採集:對每個服務,週期性地採集它所有例項的負載資料(包括cpu使用量等)匯聚為服務資料,並在對應時間視窗(window大小可配置)對資料進行平滑處理。例如每10s採集一個例項的cpu使用量匯聚為服務的cpu使用量,使用1分鐘的時間視窗內服務的cpu使用量均值作為該時間視窗對應的資料。在監控採集和資料處理過程中,使用絕對中位差演算法來剔除各類異常離群資料點。

  • 畫像構建:對每個服務,計算出過去N天每個時間片內各個時間視窗對應的cpu使用量,對一個時間片而言使用滑動視窗取其中最大的K個視窗資料均值作為該時間片的cpu使用量,這樣可以得到每個服務在過去N天每個時間片內的cpu使用量資料;同時計算相鄰兩個時間片的流量增長率,即(下個時間片流量-當前時間片流量)/當前時間片流量。後續預測彈性中會根據時間片流量和流量增長率來預測未來某時間片的流量。

4.3 容量畫像

目標:

刻畫服務的容量需求,一般用該服務的峰值cpu利用率來代替。例如一個服務在穩定時峰值cpu利用率達60%表示至少為該服務留有40%的cpu buffer來保障其穩定性。

容量畫像構建:

  • 容量與延遲:假定服務吞吐和流量不變的情況下,該服務的延遲往往與留有的cpu buffer呈反比,即留有的cpu buffer越少,延遲增長的越多。在百度Feed業務線中,非核心鏈路上的服務即使有少量的延遲上漲,也不會對系統出口延遲有直接影響,因此相比核心鏈路,非核心鏈路上的服務可以留有較少的cpu bufffer。

  • 整體方法:不同服務的極限吞吐和對應的峰值cpu利用率是不同的,整體上通過機器學習方法為每個服務構建效能曲線,刻畫出每個服務需要留多少cpu buffer合適,整體方法如下圖。

  • 特徵獲取:通過例項監控採集+例項導流壓測獲取不同負載下服務的延遲資料。

  • 模型構建:對服務的qps、cpu利用率、機器負載等一系列容器和機器的監控指標與服務延遲關係進行建模:f(qps, X)=latency。

  • 畫像計算:基於延遲模型,評估各服務在延遲可接受範圍內(核心服務延遲不允許上漲,非核心服務延遲允許一定閾值的上漲)的極限吞吐和對應的cpu利用率。

05 彈性策略

為應對不同的業務伸縮場景,我們構建如下三類彈性策略來支撐業務彈性伸縮:

預測彈性:對於彈性較低的服務,根據各時間片內的流量波動,對未來流量進行預測提前對服務容量進行規劃調整。

負載反饋彈性:對於彈性較高的服務,根據近實時服務負載變化,及時對服務容量進行伸縮確保服務穩定。

定時彈性:有些服務在流量高峰期變化較大,在非高峰期變化較小,在高峰期需要提供最大容量來保障穩定性,在非高峰期不需要頻繁調整容量,通過定時彈性在高峰期來臨之前擴容,在高峰期過後進行縮容,高峰期和非高峰期期間容量保持不變。

5.1 預測彈性

目標:

根據服務配置的時間片,在當前時間片內對未來時間片的流量進行預測,根據預測流量對服務進行提前擴容、延遲縮容來應對不同的流量變化。

流量預測:

  • 對於當前時間,結合流量畫像中上個時間片流量、當前時間片流量和下個時間片流量來計算,其中上個時間片流量、當前時間片流量、下個時間片流量都取過去N天對應時間片的最大流量,分別記為prev、cur和next。

  • 針對prev、cur、next的 大小關係,對流量趨勢走向分為如下圖4種case。

  • case-1:prev < cur < next,整體流量處於上漲趨勢中;當前應該為下個時間片的流量上漲做好準備,進行提前擴容

  • case-2:prev > cur < next,整體流量從下降趨勢扭轉為上漲趨勢;當前應該為下個時間片的流量上漲做好準備,進行提前擴容

  • case-3:prev < cur > next,整體流量從上漲趨勢扭轉為下降趨勢,當前時間片處於流量高峰狀態,不做任何動作

  • case-4:prev > cur > next,整體流量處於下降趨勢,執行縮容動作

擴/縮容策略:

  • 對於需要擴縮容的場景(如上case-1、case-2和case-4)分別計算出目標流量,其中目標流量=max(目標流量1,目標流量2)。

  • 目標容量1根據上述4類case的流量來計算:

  • 對於case-1和case-2,目標流量1等於next(相當於提前擴容)。

  • 對於case-4,目標流量1等於cur(這裡不是根據下個時間片的流量來縮容,否則容量可能扛不住當前時間片,這裡僅根據當前時間片流量來縮容,相當於延遲縮容)。

  • 目標流量2=當前流量*(過去N天當前時間片與下個時間片的最大增長率),其中當前流量採集最近K個時間視窗對應的cpu使用量。

  • 根據目標流量和服務的容量畫像(即該服務需要留多少cpu buffer)計算出目標容量,根據目標容量計算出該服務的目標例項數,聯動PaaS對服務進行橫向伸縮。

5.2 負載反饋彈性

目標:

根據服務近實時的負載情況,及時調整服務容量以應對流量突增變化。

擴/縮容策略:

  • 資料採集:

  • 通用監控:採集服務的近實時通用負載,例如cpu使用量,cpu使用率等。

  • 自定義監控:支援以Prometheus metric方式自定義業務監控指標,例如服務的延遲指標、吞吐指標等。

  • 採集週期可配置,通常使用滑動視窗的方式對監控指標進行聚合判斷。

  • 擴/縮容決策:根據服務的通用負載資料和自定義負載資料,結合服務的容量畫像,計算出服務需要的目標例項數並進行橫向擴縮容操作。

5.3 定時彈性

目標:

某些服務的流量在非高峰期波動較小沒必要頻繁調整容量,高峰期和非高峰期期望固定但不同的容量。

擴/縮容策略:

  • 計算流量畫像中高峰期和非高峰期內相應時間片的最大流量。

  • 根據最大流量和容量畫像計算服務在高峰期和非高峰期對應的目標容量。

  • 根據目標容量,在高峰期來臨之前定時觸發擴容動作(橫向擴容),在高峰期過後定時觸發縮容動作(橫向縮容),整體效果如下圖。

5.4 彈性實踐

  • 上述三類彈性策略可根據配置分開獨立使用,也可以按需組合使用:

  • 對於彈性較高的function類計算,可使用負載反饋彈性實現FaaS效果,對於彈性較低的後端重計算服務,可三類彈性組合使用;

  • 當三類策略組合使用時,由於都對服務的例項數進行調整並同時生效,三類策略之間存在優先順序,定時彈性>預測彈性>負載反饋彈性;

  • 當負載反饋彈性和預測彈性或定時彈性組合使用時,負載反饋彈性只能執行擴容動作不能進行縮容,縮容交由預測彈性或定時彈性執行。因為當某服務cpu負載比較低時,可能是因為預測彈性提前為下個時間片的流量做準備而進行擴容導致的,此時不能按照負載反饋彈性進行縮容,對定時彈性也是同理。

  • 重試機制:

  • 預測彈性和定時彈性的執行頻率較低,涉及一些策略計算及呼叫PaaS對服務例項數進行修改,整體操作不是原子性的,需要有重試機制;

  • 負載反饋彈性高頻執行,可根據服務需求按需進行重試。

  • 目標容量校驗:上述每個彈性策略修改服務目標例項數都需要進行一定的校驗。

  • 限制目標例項數在合理區間範圍:將目標例項數和每個服務容量畫像中配置的例項上下限做比較,超過則平滑至上下限閾值;

  • 限制單次擴縮容步長:將目標例項數和當前例項數做對比,限制每次擴縮容的比例,防止單次擴容太多導致資源不足,也防止縮容太多導致單例項流量飆升出現記憶體oom。

06 穩定性保障

如何在大規模頻繁動態調整服務容量的同時保障服務穩定性至關重要,我們從巡檢和干預止損的角度來建設相應穩定效能力,通過巡檢防患於未然,通過一鍵干預快速止損。

彈性巡檢:週期性地觸發服務例項遷移,檢驗服務的彈效能力,提前暴露詞典檔案依賴異常等導致的伸縮失敗。

容量巡檢:為各類服務配置告警策略,週期性地巡檢服務各項資源容量,當容量不足時觸發告警或一鍵預案。

狀態巡檢:檢查各服務狀態是否正常輪轉,防止服務狀態異常,例如高峰期和非高峰期對應不同的服務容量狀態。

一鍵干預:提供快速止損能力,定期線上演練防止能力退化,包括一鍵退出serverless預案、一鍵開啟/關閉例項軟硬限預案等。

07 總結

整體工作圍繞Serverless展開,通過彈性、流量、容量多維度的服務畫像刻畫每個服務的個性化特點,基於畫像構建多類彈性策略,滿足服務各類伸縮場景,有效地實現服務資源按需使用。當前Serverless已落地百度Feed業務線10w服務例項數規模,有效地降低了業務執行成本。

接下來,Serverless將聚焦兩個方向:熱點事件的容量保障及應用機器學習提升流量畫像預測精確度,持續接入更大規模的服務為業務創造價值!

——END——

推薦閱讀:

圖片動畫化應用中的動作分解方法

效能平臺數據提速之路

採編式AIGC視訊生產流程編排實踐

百度工程師漫談視訊理解

百度工程師帶你瞭解Module Federation

巧用Golang泛型,簡化程式碼編寫