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泛型,簡化代碼編寫