高可用架構(gòu)設(shè)計(jì)之無(wú)狀態(tài)服務(wù)
高可用架構(gòu)設(shè)計(jì)之無(wú)狀態(tài)服務(wù)
笑談架構(gòu)設(shè)計(jì)
事故的發(fā)生是量的積累的結(jié)果,任何事情都沒有表面看起來(lái)那么簡(jiǎn)單,在軟件運(yùn)行的過(guò)程中,隨著用戶量的增加,不考慮高可用,遲早有一天會(huì)發(fā)生故障,不得事先考慮高可用設(shè)計(jì),而高可用是一門龐大的學(xué)問
你想知道我在設(shè)計(jì)一個(gè)高可用系統(tǒng)會(huì)考慮哪些內(nèi)容嗎?在架構(gòu)設(shè)計(jì)的過(guò)程中
- 考慮方案選型會(huì)帶來(lái)哪些坑,最差的情況下需要考慮故障發(fā)生的緊急解決方案
- 需要監(jiān)控系統(tǒng),在故障發(fā)生時(shí)、發(fā)生時(shí)有所感知
- 需要自動(dòng)化恢復(fù)方案,自動(dòng)化提前處理預(yù)警方案
- 在代碼層面需要考慮處理速度、代碼性能、報(bào)錯(cuò)處理
- 還要考慮把故障降低到最小:服務(wù)降級(jí)、限流、熔斷
- 等等
這篇文章主要介紹無(wú)狀態(tài)服務(wù)在架構(gòu)層面,如何保證可高用
無(wú)狀態(tài)服務(wù):在任何時(shí)候服務(wù)都不存儲(chǔ)數(shù)據(jù)(除緩存),可以任意銷毀創(chuàng)建,用戶數(shù)據(jù)不會(huì)發(fā)生丟失,可以任意切換到任何一個(gè)副本,不影響用戶”無(wú)狀態(tài)服務(wù)的高可用旨在任何情況下數(shù)據(jù)都不丟失,服務(wù)都不發(fā)生故障,在某些服務(wù)發(fā)生故障時(shí)保證影響最小,并可以快速恢復(fù)
可以從這幾個(gè)方面考慮
- 冗余部署:至少多部署一個(gè)節(jié)點(diǎn),避免單點(diǎn)問題
- 垂直擴(kuò)展:增加單機(jī)性能
- 水平擴(kuò)展:流量激增可快速擴(kuò)容
冗余部署
在單點(diǎn)架構(gòu)中,隨著數(shù)據(jù)數(shù)據(jù)量增加,單點(diǎn)負(fù)載壓力過(guò)大,容易產(chǎn)生服務(wù)崩潰不可用的情形,對(duì)于無(wú)狀態(tài)服務(wù),可以考慮部署多個(gè)節(jié)點(diǎn)的服務(wù)來(lái)分散壓力
對(duì)于如何調(diào)度來(lái)臨的請(qǐng)求,可以參考負(fù)載均衡的方式,盡可能的保證充分的利用服務(wù)器的資源
- 無(wú)狀態(tài)服務(wù):不需要存儲(chǔ)數(shù)據(jù)的服務(wù),即使節(jié)點(diǎn)掛掉再重啟,不會(huì)發(fā)生數(shù)據(jù)丟失
- 負(fù)載均衡:把大量請(qǐng)求分散到不同節(jié)點(diǎn)上的一種算法
無(wú)狀態(tài)服務(wù)的負(fù)載均衡
可以使用負(fù)載均衡中提供的四種算法
- 隨機(jī)均衡算法:已知后端服務(wù)器列表,隨機(jī)請(qǐng)求,數(shù)據(jù)量越大越趨近于均衡
- 輪詢算法:輪流請(qǐng)求后端服務(wù)器
前兩種算法存在的問題是后端服務(wù)器在負(fù)載壓力不同或服務(wù)器配置不同時(shí),不能保證壓力小的多分配,壓力大的小分配,于是引入
- 加權(quán)輪循算法:按照后端服務(wù)器的抗壓能力,負(fù)載情況分配更高的權(quán)重,更容易命中,減少宕機(jī)風(fēng)險(xiǎn),按權(quán)重順序的分配到后端服務(wù)器上
- 加權(quán)隨機(jī)法:和加權(quán)輪訓(xùn)算法一樣,不同的是分配是按權(quán)重隨機(jī)的,比如有多臺(tái)權(quán)重一致的情況,隨機(jī)訪問,那就和隨機(jī)算法有同樣的問題,數(shù)據(jù)量大時(shí)才趨近于均衡,數(shù)據(jù)量小時(shí)有可能重復(fù)訪問同一臺(tái)權(quán)重一致的機(jī)器
- [加權(quán)]最小連接數(shù)算法:這是最智能的一種算法,根據(jù)服務(wù)器當(dāng)前的連接數(shù)來(lái)選取,更容易命中處理速度快的服務(wù)器
上面的算法使用于無(wú)狀態(tài)應(yīng)用,假如要保存通信狀態(tài),需要使用
- 源地址哈希算法:對(duì)源地址做hash,可以保證相同的請(qǐng)求最終都是落在同一臺(tái)機(jī)器上,不需要重復(fù)建立連接
負(fù)載均衡算法如何選擇?
首先拋棄隨機(jī)算法,最簡(jiǎn)單的配置可以使用基本的輪訓(xùn)算法,它適用于服務(wù)器配置一致,比如使用虛擬機(jī),可以動(dòng)態(tài)調(diào)整服務(wù)器配置的場(chǎng)景,同時(shí)要保證專用虛擬機(jī),上面不會(huì)部署其他應(yīng)用的情況
但是服務(wù)器上往往會(huì)安裝多個(gè)應(yīng)用,那就要考慮在加權(quán)輪訓(xùn)和最小連接數(shù)中做選擇
加權(quán)輪訓(xùn)適用于短連接場(chǎng)景,比如HTTP服務(wù),在k8s中因?yàn)槊總€(gè)pod都是獨(dú)立的,默認(rèn)service策略是非加權(quán)輪訓(xùn)
- 最小連接數(shù)適用于長(zhǎng)連接,比如FTP等
如果系統(tǒng)架構(gòu)中考慮到無(wú)cookie功能的場(chǎng)景,可以用源地址hash算法,把源IP一直映射到同一臺(tái)rs上,在k8s中叫會(huì)話保持模式,每次轉(zhuǎn)發(fā)到同一個(gè)pod上
建議:
- 如果上了容器直接交給k8s來(lái)做調(diào)度,使用cookie做會(huì)話保持,算法使用默認(rèn)輪訓(xùn),具體調(diào)度未來(lái)k8s文章里會(huì)做詳細(xì)介紹
- 使用長(zhǎng)連接的應(yīng)用(FTP、socket,或者用于下載連接),選擇加權(quán)最小連接數(shù)
- 短連接應(yīng)用(靜態(tài)網(wǎng)站、微服務(wù)組件等),選擇加權(quán)輪訓(xùn),用cookie來(lái)做會(huì)話保持,減少session的設(shè)計(jì),不僅會(huì)提高代碼復(fù)雜度,也會(huì)增加服務(wù)端負(fù)載情況,不利于分布式應(yīng)用
高并發(fā)應(yīng)用的識(shí)別
主要指標(biāo)QPS每秒處理響應(yīng)數(shù),比如每天有10w的pv
- 公式 (100000 * 80%) / (86400*20%) = 4.62 QPS(峰值QPS)
公式原理:每天80%的訪問集中在20%的時(shí)間里,這20%時(shí)間叫做峰值時(shí)間。
比如我做的系統(tǒng)托管了最高5w臺(tái)機(jī)器,每臺(tái)機(jī)器每次分鐘有一次PV,時(shí)間比較均勻那就是
- ((60*24)*50000)/(86400)=833 QPS
一般上百的量級(jí)就可以叫高并發(fā)了,網(wǎng)上查到的資料微博每天1億多pv的系統(tǒng)一般也就1500QPS,5000QPS峰值。
除了QPS還有服務(wù)響應(yīng)時(shí)間、并發(fā)用戶數(shù)指標(biāo)可以參考
在服務(wù)器負(fù)載高的時(shí)候,表現(xiàn)在處理速度變慢、網(wǎng)絡(luò)斷連、服務(wù)處理失敗、異常報(bào)錯(cuò)等問題,具體問題要具體分析,不可一概而論
可以通過(guò)監(jiān)控,來(lái)獲得服務(wù)器性能狀態(tài),動(dòng)態(tài)調(diào)整、重試,達(dá)到服務(wù)可用性的保證,減少維護(hù)成本,通常單純服務(wù)器壓力大的時(shí)候可以考慮垂直擴(kuò)展
垂直擴(kuò)展
垂直擴(kuò)展是增加服務(wù)器單機(jī)的處理能力,主要有三種方式
- 服務(wù)器升配:集中在CPU、內(nèi)存、swap、磁盤容量或者網(wǎng)卡等
- 硬件性能:磁盤SSD、調(diào)整系統(tǒng)參數(shù)等
- 架構(gòu)調(diào)整:軟件層面使用異步、緩存、無(wú)鎖結(jié)構(gòu)等
增強(qiáng)單機(jī)性能的方式是最快最容易的方式,但是單機(jī)性能之中是存在極限,同時(shí)單機(jī)部署時(shí)如果產(chǎn)生故障,對(duì)應(yīng)用來(lái)說(shuō)打擊是致命的,我們應(yīng)該保證應(yīng)用時(shí)刻處于可用的狀態(tài),也就是俗話說(shuō)的保證5個(gè)9的可靠性
水平自動(dòng)伸縮
知道了單機(jī)的局限以后,考慮使用水平伸縮的方式
水平伸縮就是壓力增加的時(shí)候,增加新的節(jié)點(diǎn)來(lái)分擔(dān)壓力,但僅僅多點(diǎn)部署還是不夠的,對(duì)于持續(xù)增長(zhǎng)的業(yè)務(wù),始終有一天會(huì)突破服務(wù)的壓力上限,如果遇到流量激增的場(chǎng)景,人工應(yīng)對(duì)肯定會(huì)措手不及,所以需要一種自動(dòng)伸縮的手段
對(duì)于私有云部署來(lái)說(shuō)可以手動(dòng)實(shí)現(xiàn)調(diào)度器,檢測(cè)系統(tǒng)狀態(tài),連通iaas層實(shí)現(xiàn)伸縮
也可以直接使用云服務(wù)器提供的彈性伸縮服務(wù)
對(duì)于容器而言,可以在iaas層彈性伸縮的情況下或者有充足node節(jié)點(diǎn)的情況下,配置自動(dòng)伸縮和調(diào)度的策略,預(yù)防單機(jī)故障
名詞解釋:iaas 基礎(chǔ)設(shè)施即服務(wù),代表對(duì)服務(wù)器、存儲(chǔ)、網(wǎng)絡(luò)等硬件資源管理的服務(wù)”注意:彈性伸縮針對(duì)的業(yè)務(wù)場(chǎng)景是無(wú)狀態(tài)服務(wù)
另外無(wú)狀態(tài)機(jī)器不足以承載請(qǐng)求流量,需要進(jìn)行水平擴(kuò)展的閾值一般QPS是千級(jí),同時(shí)在這里對(duì)數(shù)據(jù)庫(kù)也會(huì)有壓力,所以建議水平伸縮的服務(wù)器不要部署有狀態(tài)服務(wù)
對(duì)于有狀態(tài)服務(wù)壓力分散在后續(xù)的文章會(huì)有所介紹
CDN和OSS
對(duì)于一個(gè)網(wǎng)站來(lái)說(shuō),用戶交互頁(yè)面,是一個(gè)特殊的服務(wù),包含很多靜態(tài)資源,比如圖片、視頻、頁(yè)面(html/css/js),這些資源在用戶請(qǐng)求的時(shí)候需要現(xiàn)場(chǎng)下載,下載速度決定了加載速度,在web服務(wù)故障的時(shí)候,同樣應(yīng)該對(duì)用戶做出相應(yīng)
在這一層面可以考慮使用CDN內(nèi)容分發(fā)網(wǎng)絡(luò)的方式,詳見[xxx],把前端靜態(tài)數(shù)據(jù)緩存到邊緣服務(wù)器上
名詞解釋:邊緣服務(wù)器(邊緣節(jié)點(diǎn)),可以理解為和用戶交互的服務(wù)器,也可理解為靠近用戶的服務(wù)器節(jié)點(diǎn),因?yàn)榭拷脩?,減少了網(wǎng)絡(luò)傳輸使用的時(shí)間”使用了CDN的web服務(wù),可以把https證書綁定到cdn上,在回源策略可以配置回源超時(shí)、回源跟隨301/302狀態(tài)碼等配置,還可以智能壓縮網(wǎng)頁(yè)、自定義錯(cuò)誤頁(yè)面,非常方便
oss是一種特殊的存儲(chǔ)方案,以對(duì)象的形式進(jìn)行存儲(chǔ),理論上可以存儲(chǔ)無(wú)限的文件
考慮使用oss對(duì)象存儲(chǔ)并結(jié)合cdn,把媒體資源存儲(chǔ)在對(duì)象存儲(chǔ)上面,也可以把冷數(shù)據(jù)壓縮歸檔到oss上
常見的視頻網(wǎng)站大多會(huì)用到oss,微博n年以前的數(shù)據(jù)應(yīng)該就是歸檔到對(duì)象存儲(chǔ)中了
總結(jié)
本文介紹的無(wú)狀態(tài)服務(wù)常見的高可用架構(gòu)設(shè)計(jì),他們是
- 冗余部署
- 負(fù)載均衡的6種算法與算法選擇
- 垂直擴(kuò)展的好處與弊端
- 水平擴(kuò)展與水平自動(dòng)伸縮
- 哪些服務(wù)可以使用CDN和OSS
要注意無(wú)狀態(tài)應(yīng)用不應(yīng)該存儲(chǔ)session,也不存儲(chǔ)數(shù)據(jù)
本文對(duì)負(fù)載均衡的6種算法做了介紹,但是沒有介紹每個(gè)算法具體的實(shí)現(xiàn)方式,這個(gè)留給你下來(lái)研究,這些方案在實(shí)際使用的時(shí)候會(huì)有一定難度,服務(wù)不可用的故障原因任何一門都是博大精深的學(xué)問,程序員不僅是寫代碼
這里也僅僅寫了無(wú)狀態(tài)服務(wù)的部分高可用方案,不管是什么服務(wù)還是從代碼層級(jí)的設(shè)計(jì),你還知道哪些呢?
有時(shí)候比較苛刻的情況下,沒有更多的服務(wù)器資源,如何在有限服務(wù)器的情況下提高更多的代碼性能呢?
本文轉(zhuǎn)載自微信公眾號(hào)「機(jī)智的程序員小熊」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系機(jī)智的程序員小熊公眾號(hào)。