華爲雲FunctionGraph構建高可用系統的實踐

本文分享自華爲雲社區《華爲雲FunctionGraph構建高可用系統的實踐》,作者: 華爲雲PaaS服務小智。

導語

每年,網上都會報道XXX系統異常不可用,給客戶帶來巨大的經濟損失。雲服務的客戶基數更大,一旦出現問題,都將給客戶和服務自身帶來極大影響。本文將基於華爲雲FunctionGraph自身的實踐,詳細介紹如何構建高可用的Serverless計算平臺,實現客戶和平臺雙贏。

高可用介紹

高可用性[1](英語:high availability,縮寫爲 HA),IT術語,指系統無中斷地執行其功能的能力,代表系統的可用性程度。是進行系統設計時的準則之一。

業界一般使用 SLA指標來衡量系統的可用性。

服務級別協議[2](英語:service-level agreement,縮寫SLA)也稱服務等級協議、服務水平協議,是服務提供商與客戶之間定義的正式承諾。服務提供商與受服務客戶之間具體達成了承諾的服務指標——質量、可用性,責任。例如,服務提供商對外承諾99.99%的SLA,則全年服務失效時間最大爲 5.26 分鐘(365*24*60*0.001%)。

FunctionGraph直觀度量系統可用性的兩個黃金指標,SLI和時延,SLI是系統的請求成功率指標,時延是系統處理的性能。

高可用挑戰

FunctionGraph作爲華爲雲中的子服務,在構建自身能力的同時,不僅要考慮系統本身的健壯性,也要考慮周邊依賴服務的健壯性(例如依賴的身份認證服務不可用了,進行流量轉發的網關服務服務宕機了,存儲對象的服務訪問失敗了等等)。除此之外,系統依賴的硬件資源故障或者系統突然遭到流量攻擊等,面臨這些不可控的異常場景,系統如何構建自己的能力來保持業務高可用是一個很大的挑戰。圖一展示了FunctionGraph的周邊交互。

圖1 FunctionGraph的周邊交互

 

針對常見的問題,梳理出了4個大類,如表1所示。

表1 FunctionGraph常見問題總結

針對這些問題,我們總結了如下幾類通用的治理辦法:

  • 流量突變治理:過載保護+彈性擴縮容+熔斷+異步削峯+監控告警,基於防禦式的設計思想,通過過載保護+熔斷確保系統所有資源受控,然後在此基礎上通過提供極致的擴容能力來滿足大流量,合適的客戶場景推薦異步削峯來減緩系統壓力,監控告警用來及時發現過載問題。
  • 系統服務異常治理:容災架構+重試+隔離+監控告警,通過容災架構避免系統整個宕機,通過重試來減少系統異常對客戶業務的影響,通過隔離快速剝離系統異常點,防止故障擴散,通過監控告警快速發現系統服務異常問題。
  • 系統依賴服務異常治理:容災架構+緩存降級+監控告警,通過容災架構減少依賴服務單點故障,通過緩存降級確保依賴服務故障後系統仍能正常運行,通過監控告警快速發現依賴服務異常問題。
  • 變更引起治理:灰度升級+流程管控+監控告警,通過灰度升級避免正式客戶由於系統升級異常而造成的全局故障,通過流程管控將人爲變更的風險降到最低,通過監控告警快速發現變更後的故障。

FunctionGraph系統設計實踐

爲了解決表1出現的問題,FunctionGraph在架構容災、流控、重試、緩存、灰度升級、監控告警、管理流程上等多方面做了優化,可用性大幅提升。下面主要介紹一些FunctionGraph面向異常的設計實踐,在彈性能力、系統功能等暫不展開。

容災架構

實現華爲雲容災1.1架構(例:服務AZ級故障域、集羣跨AZ自愈能力、AZ級服務依賴隔離),FunctionGraph管理面和數據面集羣部署多套,每套集羣AZ隔離,實現同region內的AZ容災。如圖2所示,FunctionGraph部署多套數據面集羣(承擔FunctionGraph函數運行業務)和dispatcher調度集羣(承擔FunctionGraph的流量集羣調度任務),用來提升系容量以及容災。當前其中某個元戎集羣異常時,dispatcher調度組件能及時摘除故障集羣,並將流量分發至其他幾個集羣。

圖2 FunctionGraph簡略架構圖

分佈式無中心化架構設計,支持靈活的橫向擴縮容

這個策略是邏輯多租服務設計的關鍵,需要解決無中心化後,組件擴縮容後的重均衡問題。

靜態數據管理的無中心化:邏輯多租服務的元數據,初期由於量少,可以全部存儲到同一套中間件中。隨着客戶上量,需要設計數據的拆分方案,支持數據的分片,應對後續海量數據讀寫,以及可靠性壓力。

流量調度功能的無中心化:組件功能設計,支持無中心化(常見中心化依賴:鎖、流控值、調度任務等),流量上量後,可擴展組件副本數量,組件通過自均衡策略,完成流量的重新負載。

多維度的流控策略

FunctionGraph上的客戶函數流量最終達到runtime運行時之前,會經過多個鏈路,每個鏈路都有可能出現超過其承載閾值的流量。因此,爲了確保各個鏈路的穩定性,FunctionGraph在每條鏈路上,防禦性的追加了不同的流控策略。基本原則解決計算(cpu)、存儲(磁盤、磁盤I/0)、網絡(http連接、帶寬)上的函數粒度的資源隔離。

函數流量從客戶側觸發,最終運行起來的鏈路流控如圖3所示。

圖3 FunctionGraph流控

網關APIG流控

APIG是FunctionGraph的流量入口,支持Region級別總的流量控制,可以根據region的業務繁忙程度進行彈性擴容。同時APIG支持客戶級別的流量控制,當檢測到客戶流量異常時,可以快速通過APIG側限制客戶流量,減少個別客戶對系統穩定性的影響。

系統業務流控

針對api級別的流控

客戶流量通過APIG後,走到FunctionGraph的系統側。基於APIG流控失效的場景,FunctionGraph構建了自身的流控策略。當前支持節點級別流控、客戶api總流控、函數級別流控。當客戶流量超過FunctionGraph的承載能力時,系統直接拒絕,並返回429給客戶。

系統資源流控

FunctionGraph是邏輯多租服務,控制面和數據面的資源是客戶共享的,當非法客戶惡意攻擊時,會造成系統不穩定。FunctionGraph針對共享資源實現基於請求併發數的客戶流控,嚴格限制客戶可用的資源。另外對共享資源的資源池化來保證共享資源的總量可控制,進而保證系統的可用性。例如:http連接池、內存池、協程池。

併發數控制:構建基於請求併發數的FunctionGraph函數粒度的流控策略,FunctionGraph的客戶函數執行時間有毫秒、秒、分鐘、小時等多種類型,常規的QPS每秒請求數的流控策略在處理超長執行的請求時有先天不足,無法限制同一時刻客戶佔用的系統共享資源。基於併發數的控制策略,嚴格限制了同一時刻的請求量,超過併發數直接拒絕,保護系統共享資源。

http連接池:構建高併發的服務時,合理的維護http的長連接數量,能最大限度減少http連接的資源開銷時間,同時保證http連接數資源的可控,確保系統安全性的同時提升系統性能。業界可以參考http2的連接複用,以及fasthttp內部的連接池實現,其原理都是儘量減少http的數量,複用已有的資源。

內存池:客戶的請求和響應報文特別大,同時併發特別高的場景下,單位時間佔用系統的內存較大,當超過閾值後,會輕鬆造成系統內存溢出,導致系統重啓。基於此場景,FunctionGraph新增了內存池的統一控制,在請求入口和響應出口,校驗客戶請求報文是否超過閾值,保護系統內存可控。

協程池:FunctionGraph構建於雲原生平臺上,採用的go語言。如果每一個請求都使用一個協程來進行日誌和指標的處理,大併發請求來臨時,導致有海量的協程在併發執行,造成系統的整體性能大幅下降。FunctionGraph引入go的協程池,通過將日誌和指標的處理任務改造成一個個的job任務,提交到協程池中,然協程池統一處理,大幅緩解了協程爆炸的問題。

異步消費速率控制:異步函數調用時,會優先放到FunctionGraph的kafka中,通過合理設置客戶的kafka消費速率,確保函數實例始終夠用,同時防止過量的函數調用,導致底層資源被迅速耗光。

函數實例控制

  • 客戶實例配額:通過限制客戶總配額,防止惡意客戶將底層資源耗光,來保障系統的穩定性。當客戶業務確實有需要,可以通過申請工單的方式快速擴充客戶配額。
  • 函數實例配額:通過限制函數配額,防止單個客戶的函數將客戶的實例耗光,同時也能防止客戶配額失效,短時間內造成大量的資源消耗。另外,客戶業務如果涉及數據庫、redis等中間件的使用,通過函數實例配額限制,可以保護客戶的中間件連接數在可控範圍內。
高效的資源彈性能力

流控屬於防禦式設計思想,通過提前封堵的方式減少系統過載的風險。客戶正常業務突發上量需要大量的資源時,首先應該解決的是資源彈性問題,保證客戶業務成功的前提下,通過流控策略兜底系統出現異常,防止爆炸面擴散。FunctionGraph支持集羣節點快速彈性、支持客戶函數實例快速彈性、支持客戶函數實例的智能預測彈性等多種彈性能力,保證客戶業務突增時依然能正常使用FunctionGraph。

重試策略

FunctionGraph通過設計恰當好處的重試策略,使系統在發生異常的時候,也可以保障客戶的請求最終執行成功。如圖4所示,重試的策略一定要有終止條件,否則會造成重試風暴,更輕鬆的擊穿系統的承載上限。

圖4 重試策略

函數請求失敗重試
  • 同步請求:當客戶請求執行時,遇到系統錯誤時,FunctionGraph會將請求轉發至其他集羣,最多重試3次,確保客戶的請求,在遇到偶現的集羣異常,也可以在其他集羣執行成功。
  • 異步請求:由於異步函數對實時性要求不高,客戶函數執行失敗後,系統可以針對失敗請求做更爲精細的重試策略。當前FunctionGraph支持二進制指數退避的重試,當函數由於系統錯誤異常終止後,函數會按2,4,8,16指數退避的方法,當間隔退避到20分鐘時,後續重試均按照20分的間隔進行,函數請求重試時間最大支持6小時,當超過後,會按失敗請求處理,返回給客戶。通過二進制指數退避的方式,可以最大程度保障客戶業務的穩定性。
依賴服務間的重試
  • 中間件的重試機制:以redis爲例,當系統讀寫redis偶現失敗時,會sleep一段時間,再重複執行redis的讀寫操作,最大重試次數3次。
  • http請求重試機制:當http請求由於網絡波動,發生eof、io timeout之類的錯誤時,會sleep一段時間,在重複http的發送操作,最大重試次數3次。
緩存

緩存不僅可以加速數據的訪問,而且當依賴的服務故障時,仍然可以使用緩存數據,保障系統的可用性。從功能類別劃分,FunctionGraph需要進行緩存的組件有兩類,1是中間件,2是依賴的雲服務,系統優先訪問緩存數據,同時定期從中間件和依賴的雲服務刷新本地緩存數據。方式如圖5所示。

  • 緩存中間件數據:FunctionGraph通過發佈訂閱的方式,監聽中間件數據的變化及時更新到本地緩存,當中間件異常時,本地緩存可以繼續使用,維持系統的穩定性。
  • 緩存關鍵依賴服務數據:以華爲雲的身份認證服務IAM爲例,FunctionGraph會強依賴IAM,當客戶發起首次請求,系統會將token緩存到本地,過期時間24小時,當IAM掛掉後,不影響老的請求。FunctionGraph系統的使用。其他關鍵的雲服務依賴做法一直,都是把關鍵的數據臨時緩存到本地內存。

圖5 FunctionGraph的緩存措施

熔斷

上面的種種措施,可以保障客戶業務平穩運行,但當客戶業務出現異常一直無法恢復或者有惡意客戶持續攻擊FunctionGraph平臺,系統資源會一直浪費在異常流量上,擠佔正常客戶的資源,同時系統可能會在持續高負荷運行異常流量後出現不可預期的錯誤。針對這種場景,FunctionGraph基於函數調用量模型構建了自身的斷路器策略。具體如圖6所示,根據調用量的失敗率進行多級熔斷,保證客戶業務的平滑以及系統的穩定。

圖6 熔斷策略模型

隔離

  • 異步函數業務隔離:按照異步請求的類別,FunctionGraph將Kafka的消費組劃分爲定時觸發器消費組、專享消費組、通用消費組、異步消息重試消費組,topic同理也劃分爲對等類別。通過細分consumer消費組和topic,定時觸發器業務和大流量業務隔離,正常業務和重試請求業務隔離,客戶的業務請求得到最高優先級的保障。
  • 安全容器隔離:傳統cce容器基於cgroup進行隔離,當客戶增多,客戶調用量變大時,會偶現客戶間的互相干擾。通過安全容器可以做到虛擬機級別的隔離,客戶業務互不干擾。
灰度升級

邏輯多租服務,一旦升級出問題,造成的影響不可控。FunctionGraph支持按ring環升級(根據region上業務的風險度進行劃分)、藍綠髮布、金絲雀發佈策略,升級動作簡要描述成三個步驟:

  1. 升級前集羣的流量隔離:當前FunctionGraph升級時,優先將升級集羣的流量隔離,確保新流量不在進入升級集羣;
  2. 升級前集羣的流量遷移、優雅退出:將流量遷移到其他集羣,同時升級集羣的請求徹底優雅退出後,執行升級操作;
  3. 升級後的集羣支持流量按客戶遷入:升級完成後,將撥測客戶的流量轉發到升級集羣,待撥測用例全部執行成功後,在將正式客戶的流量遷進來。
監控告警

當FunctionGraph出現系統無法兜住的錯誤後,我們給出的解決措施就是構建監控告警能力,快速發現異常點,在分鐘級別恢復故障,最大程度減少系統的中斷時間。作爲系統高可用的最後一道防線,快速發現問題的能力至關重要,FunctionGraph圍繞着業務關鍵路徑,構建了多個告警點。如表2所示。

表2: FunctionGraph構建的監控告警
流程規範

上面的一些措施從技術設計層面解決系統可用性的問題,FunctionGraph從流程上也形成了一套規章制度,當技術短期無法解決問題後,可以通過人爲介入快速消除風險。具體有如下團隊運作規範:

  • 內部war room流程:遇到現網緊急問題,團隊內部快速組織起關鍵角色,第一時間恢復現網故障;
  • 內部變更評審流程:系統版本在測試環境浸泡驗證沒問題後,在正式變更現網前,需要編寫變更指導書,識別變更功能點和風險點,經團隊關鍵角色評估後,才准許上現網,通過標準的流程管理減少人爲變更導致異常;
  • 定期現網問題分析覆盤:例行每週現網風險評估、告警分析覆盤,通過問題看系統設計的不足之處,舉一反三,優化系統。
客戶端容災

業界最先進的雲服務,對外也無法承諾100%的SLA。所以,當系統自身甚至人力介入都無法在急短時間內快速恢復系統狀態,這時候和客戶共同設計的容災方案就顯得至關重要。一般,FunctionGraph會和客戶一同設計客戶端的容災方案,當系統持續出現異常,客戶端需要針對返回進行重試,當失敗次數達到一定程度,需要考慮在客戶端側觸發熔斷,限制對下游系統的訪問,同時及時切換到逃生方案。

總結

FunctionGraph在做高可用設計時,整體遵循如下原則“冗餘+故障轉移”,在滿足業務基本需求的情況下,保證系統穩定後在逐步完善架構。

冗餘+故障轉移”包括以下能力:

容災架構:多集羣模式、主備模式

過載保護:流控、異步削峯、資源池化

故障治理:重試、緩存、隔離、降級、熔斷

灰度發佈:灰度切流、優雅退出

客戶端容災:重試、熔斷、逃生

未來,FunctionGraph會持續從系統設計、監控、流程幾個維度持續構建更高可用的服務。如圖7所示,通過構建監測能力快速發現問題,通過可靠性設計快速解決問題,通過流程規範來減少問題,持續提升系統的可用性能力,爲客戶提供SLA更高的服務。

圖7: FunctionGraph高可用迭代實踐

參考文獻

[1]高可用定義:https://zh.wikipedia.org/zh-hans/%E9%AB%98%E5%8F%AF%E7%94%A8%E6%80%A7

[2]SLA定義:https://zh.wikipedia.org/zh-hans/%E6%9C%8D%E5%8A%A1%E7%BA%A7%E5%88%AB%E5%8D%8F%E8%AE%AE

作者:安 校稿:舊浪、聞若

點擊關注,第一時間瞭解華爲雲新鮮技術~

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章