高可用架構設計之無狀態服務

事故的發生是量的積累的結果,任何事情都沒有表面看起來那麼簡單,在軟件運行的過程中,隨着用戶量的增加,不考慮高可用,遲早有一天會發生故障,不得事先考慮高可用設計,而高可用是一門龐大的學問。

在設計一個高可用系統會考慮哪些內容?

在架構設計的過程中,考慮方案選型會帶來哪些坑,最差的情況下需要考慮故障發生的緊急解決方案;需要監控系統,在故障發生時、發生時有所感知;需要自動化恢復方案,自動化提前處理預警方案;在代碼層面需要考慮處理速度、代碼性能、報錯處理;還要考慮把故障降低到最小:服務降級、限流、熔斷等等。

這篇文章主要介紹無狀態服務在架構層面,如何保證高可用。

無狀態服務:在任何時候服務都不存儲數據 (除緩存),可以任意銷燬創建,用戶數據不會發生丟失,可以任意切換到任何一個副本,不影響用戶” 無狀態服務的高可用在任何情況下數據都不丟失,服務都不發生故障,在某些服務發生故障時保證影響最小,並可以快速恢復。

可以從這幾個方面考慮:

冗餘部署:至少多部署一個節點,避免單點問題

垂直擴展:增加單機性能

水平擴展:流量激增可快速擴容

冗餘部署

在單點架構中,隨着數據數據量增加,單點負載壓力過大,容易產生服務崩潰不可用的情形,對於無狀態服務,可以考慮部署多個節點的服務來分散壓力

對於如何調度來臨的請求,可以參考負載均衡的方式,儘可能的保證充分的利用服務器的資源

無狀態服務:不需要存儲數據的服務,即使節點掛掉再重啓,不會發生數據丟失。

負載均衡:把大量請求分散到不同節點上的一種算法。

無狀態服務的負載均衡

可以使用負載均衡中提供的四種算法

隨機均衡算法:已知後端服務器列表,隨機請求,數據量越大越趨近於均衡

輪詢算法:輪流請求後端服務器。

[加權] 最小連接數算法:這是最智能的一種算法,根據服務器當前的連接數來選取,更容易命中處理速度快的服務器。

上面的算法使用於無狀態應用,假如要保存通信狀態,需要使用

源地址哈希算法:對源地址做 hash,可以保證相同的請求最終都是落在同一臺機器上,不需要重複建立連接。

負載均衡算法如何選擇?

首先拋棄隨機算法,最簡單的配置可以使用基本的輪訓算法,它適用於服務器配置一致,比如使用虛擬機,可以動態調整服務器配置的場景,同時要保證專用虛擬機,上面不會部署其他應用的情況

但是服務器上往往會安裝多個應用,那就要考慮在加權輪訓和最小連接數中做選擇

加權輪訓適用於短連接場景,比如 HTTP 服務,在 k8s 中因爲每個 pod 都是獨立的,默認 service 策略是非加權輪訓

最小連接數適用於長連接,比如 FTP 等

如果系統架構中考慮到無 cookie 功能的場景,可以用源地址 hash 算法,把源 IP 一直映射到同一臺 rs 上,在 k8s 中叫會話保持模式,每次轉發到同一個 pod 上

建議:

如果上了容器直接交給 k8s 來做調度,使用 cookie 做會話保持,算法使用默認輪訓;

使用長連接的應用 (FTP、socket,或者用於下載連接),選擇加權最小連接數;

短連接應用 (靜態網站、微服務組件等),選擇加權輪訓,用 cookie 來做會話保持,減少 session 的設計,不僅會提高代碼複雜度,也會增加服務端負載情況,不利於分佈式應用。

高併發應用的識別

主要指標 QPS 每秒處理響應數,比如每天有 10w 的 pv

公式原理:每天 80% 的訪問集中在 20% 的時間裏,這 20% 時間叫做峯值時間。

比如我做的系統託管了最高 5w 臺機器,每臺機器每次分鐘有一次 PV,時間比較均勻那就是

((60*24)*50000)/(86400)=833 QPS

一般上百的量級就可以叫高併發了,網上查到的資料微博每天 1 億多 pv 的系統一般也就 1500QPS,5000QPS 峯值。

除了 QPS 還有服務響應時間、併發用戶數指標可以參考

可以通過監控,來獲得服務器性能狀態,動態調整、重試,達到服務可用性的保證,減少維護成本,通常單純服務器壓力大的時候可以考慮垂直擴展

垂直擴展

垂直擴展是增加服務器單機的處理能力,主要有三種方式

服務器升配:集中在 CPU、內存、swap、磁盤容量或者網卡等

硬件性能:磁盤 SSD、調整系統參數等

架構調整:軟件層面使用異步、緩存、無鎖結構等

增強單機性能的方式是最快最容易的方式,但是單機性能之中是存在極限,同時單機部署時如果產生故障,對應用來說打擊是致命的,我們應該保證應用時刻處於可用的狀態,也就是俗話說的保證 5 個 9 的可靠性

水平自動伸縮

知道了單機的侷限以後,考慮使用水平伸縮的方式

水平伸縮就是壓力增加的時候,增加新的節點來分擔壓力,但僅僅多點部署還是不夠的,對於持續增長的業務,始終有一天會突破服務的壓力上限,如果遇到流量激增的場景,人工應對肯定會措手不及,所以需要一種自動伸縮的手段

對於私有云部署來說可以手動實現調度器,檢測系統狀態,連通 iaas 層實現伸縮

也可以直接使用雲服務器提供的彈性伸縮服務

對於容器而言,可以在 iaas 層彈性伸縮的情況下或者有充足 node 節點的情況下,配置自動伸縮和調度的策略,預防單機故障

名詞解釋:iaas 基礎設施即服務,代表對服務器、存儲、網絡等硬件資源管理的服務” 注意:彈性伸縮針對的業務場景是無狀態服務

另外無狀態機器不足以承載請求流量,需要進行水平擴展的閾值一般 QPS 是千級,同時在這裏對數據庫也會有壓力,所以建議水平伸縮的服務器不要部署有狀態服務

CDN 和 OSS

對於一個網站來說,用戶交互頁面,是一個特殊的服務,包含很多靜態資源,比如圖片、視頻、頁面 (html/css/js),這些資源在用戶請求的時候需要現場下載,下載速度決定了加載速度,在 web 服務故障的時候,同樣應該對用戶做出相應

在這一層面可以考慮使用 CDN 內容分發網絡的方式,詳見 [xxx],把前端靜態數據緩存到邊緣服務器上

名詞解釋:邊緣服務器 (邊緣節點),可以理解爲和用戶交互的服務器,也可理解爲靠近用戶的服務器節點,因爲靠近用戶,減少了網絡傳輸使用的時間” 使用了 CDN 的 web 服務,可以把 https 證書綁定到 cdn 上,在回源策略可以配置回源超時、回源跟隨 301/302 狀態碼等配置,還可以智能壓縮網頁、自定義錯誤頁面,非常方便

oss 是一種特殊的存儲方案,以對象的形式進行存儲,理論上可以存儲無限的文件

考慮使用 oss 對象存儲並結合 cdn,把媒體資源存儲在對象存儲上面,也可以把冷數據壓縮歸檔到 oss 上

常見的視頻網站大多會用到 oss,微博 n 年以前的數據應該就是歸檔到對象存儲中了。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/R76suDCWytv5l6eLkBAh0Q