終于有人把 "高可用" 說清楚了!
圖片來自 Pexels
無論是一個域,一個 BG,還是一個站點,雖然范圍有大有小,對象有所不同,但其高可用的理念都是相通的,今天將自己對高可用的一點點思考以及總結(jié)的“nPRT 公式”分享給大家。
本文采用“高可用是什么,為什么要高可用,怎么做高可用,為什么這么做,軟件風(fēng)險又在哪里”的邏輯來介紹。
高可用是一種控制風(fēng)險的能力
高可用是一種面向風(fēng)險設(shè)計,使系統(tǒng)具備控制風(fēng)險,提供更高的可用性的能力。
為什么要高可用
對于一個公司而言,“為什么要高可用”可以完整理解為“公司為什么要(做系統(tǒng))高可用”。
以公司為對象,從內(nèi)看包括:人,軟件(物),硬件(物);從外看包括:客戶,股東,社會;從自身看包括:公司。
高可用的大前提,所有事物都不是 100% 可靠的:
- 所有事物都是變化的(唯一不變的是變化)。
 - 所有變化的都不是 100% 可靠的。
 - 結(jié)論:所有事物都不是 100% 可靠的。
 
內(nèi)因,人、物都不是 100% 可靠的:
- 從人的層面:人都是有可能犯錯的。
 - 從軟件層面:軟件都是有可能有 Bug 的。
 - 從硬件層面:硬件都是有可能會壞的。
 
從概率學(xué)角度分析,凡是有可能會出錯的,只要變化次數(shù)足夠多,最終出錯的概率會無限趨向于 1。
外因,無高可用,對外影響面是很大的:
- 從客戶角度:無高可用,客戶服務(wù)可能會中斷。
 - 從股東層面:無高可用,股價可能會下跌。
 - 從社會角度:無高可用,社會秩序可能受影響。
 
根因(本質(zhì)):控制風(fēng)險。
從公司自身角度:控制風(fēng)險,保障公司價值,避免傷及根本。
如何做高可用
如何做高可用,本質(zhì)上就是:如何控制風(fēng)險。
風(fēng)險相關(guān)概念
風(fēng)險:指未來會發(fā)生危害的一種可能性,但實際未發(fā)生,記為r。
故障:指已發(fā)生或正在發(fā)生危害的一種事實,是風(fēng)險變現(xiàn)實的結(jié)果。
風(fēng)險概率:指一個風(fēng)險變故障的概率。用它來表示風(fēng)險觸發(fā)為故障的難易程度,記為 P(r)。
故障影響范圍:指在單位時間內(nèi),一個故障造成的危害影響,記為 R(r)。
故障影響時長:指一個故障持續(xù)的時間,記為 T(r)。
故障影響面:指一個故障影響范圍乘以故障影響時長的總和。這里用故障影響面來表示故障總的危害程度,記為 F(r)。
風(fēng)險期望:指每個風(fēng)險變故障的概率乘以每個風(fēng)險變故障后的故障影響面的總和。這里用風(fēng)險期望來表示風(fēng)險的潛在危害程度,記為 E(r)。
風(fēng)險期望的公式
根據(jù)上節(jié)的定義,可以推導(dǎo)出風(fēng)險期望的公式如下:
r 代表風(fēng)險,風(fēng)險期望會隨著風(fēng)險的數(shù)量 n 和每個風(fēng)險的 P、R、T 下降而下降,簡稱 nPRT 公式。(注:如果要引用該公式請注明出處。)
控制風(fēng)險的 4 大因素(nPRT)
①減少風(fēng)險數(shù)量,n
從源頭遠(yuǎn)離風(fēng)險,做到與風(fēng)險載體無連接,無關(guān)系;那么該風(fēng)險概率就是0,也不關(guān)心該風(fēng)險發(fā)生后的故障影響面是大是小,完全不關(guān)心。
例如:重大節(jié)日活動,施行全站封網(wǎng),變更的數(shù)量就會得到一個明顯的下降,就是典型的減少風(fēng)險數(shù)量。
例如:系統(tǒng) A 完全不依賴 Oracle,那系統(tǒng) A 就不用關(guān)心 Oracle 的任何風(fēng)險,哪怕美國總統(tǒng)突然緊急宣布 Oracle 立即立刻禁止在中國使用,系統(tǒng) A 也無所謂。
例如:最近新冠大流行,人傳人很可怕,如果你今天選擇不上班不出門,那你今天就不用擔(dān)心被外面的行人和同事傳染。
②降低風(fēng)險變故障的概率(即:增加風(fēng)險變故障的難度),P
把風(fēng)險當(dāng)成一個對象看待,給它層層設(shè)卡,增加風(fēng)險變故障的門檻和難度,不要再讓“不小心多了一個空格或字符,系統(tǒng)就掛了”這種慘案輕易出現(xiàn)。
例如:人員 B 要對系統(tǒng) C 進(jìn)行變更,可以對人員 B 增加變更認(rèn)證考試,對變更內(nèi)容要求線下(或仿真)測試,對變更內(nèi)容進(jìn)行 CR,系統(tǒng) C 提供變更效果預(yù)覽能力(類似監(jiān)控模式或試運行)。
萬一人員 B 想惡意變更搞破壞,還可以增加非同人復(fù)核,系統(tǒng)C可以增加防錯設(shè)計進(jìn)行保護(hù)等等。
例如:以新冠為例,帶口罩,勤洗手,多通風(fēng)等就可以降低染上新冠的概率。
③減小故障影響范圍,R
以大拆小,將一個整體拆分成 N 個小的個體,每個個體之間進(jìn)行相互隔離,單個個體出問題僅影響單個個體,實現(xiàn)小而美。
例如:分布式架構(gòu)就是這個的典范,集中式一損俱損,分布式一損即 N 分之一損。
例如:以新冠為例,網(wǎng)格化管理,各省或市間的流動進(jìn)行限制,跨省必須核酸+隔離 14 天,有效控制新冠的傳播范圍。
④縮短故障影響時長,T
故障影響時長由故障發(fā)現(xiàn)時間和故障止血時間決定,所以要早發(fā)現(xiàn)早止血。
發(fā)現(xiàn)方式分為:事前的預(yù)警,事后的告警。盡可能朝事前預(yù)警去做,給止血爭取時間甚至將風(fēng)險扼殺在搖籃中。
止血方式分為:切換,回滾,擴(kuò)容,降級 or 限流,BUG 修復(fù)等。故障出現(xiàn)時第一優(yōu)先原則為快速止血(如切換、回滾、擴(kuò)容),嚴(yán)禁去定位根因;當(dāng)無法快速止血時以少流血為第二優(yōu)先原則,如降級、限流。
止血效率:自動 vs 人工 ;一鍵化 vs 多步操作。盡可能用自動化去代替人工操作,若人工操作時盡量實現(xiàn)一鍵化,提升止血速度。
例如:對于容量水位,可以在警戒線之前劃一條預(yù)警線,提前預(yù)警,從容應(yīng)對。
例如:分布式應(yīng)用集群,任何一臺應(yīng)用服務(wù)器有問題時,負(fù)載均衡會通過心跳檢查自動把有問題的應(yīng)用服務(wù)器剔除,將請求轉(zhuǎn)發(fā)給其他(熱)備份冗余的服務(wù)器上。
例如:以新冠為例,但由于每個生命都是獨一無二的,沒有辦法切換,也沒有辦法回滾,也不能降級(涉及人道主義),只能對癥下藥慢慢治療。
高可用架構(gòu)設(shè)計的 7 大核心原則
根據(jù) nPRT 公式,在高可用架構(gòu)設(shè)計時有以下 7 個核心原則:
①少依賴原則:能不依賴的,盡可能不依賴,越少越好(n)
由于所有事物都不是 100% 可靠的,當(dāng) 2 個事物之間有了關(guān)系,那么就會相互影響,就互為對方的一個風(fēng)險,一個出問題可能會影響另外一個。我們統(tǒng)一用依賴來泛指這里的“關(guān)系”。
例如:一個系統(tǒng)同時依賴 Oracle,MySQL,OB 三種關(guān)系型數(shù)據(jù)庫,少依賴原則是改成僅依賴最成熟穩(wěn)定的 OB,不依賴 Oracle 和 MySQL。
什么場景適合多依賴?當(dāng)引入依賴(n 變大)可以減小 PRT 中的一個或多個,且使 E(r) 整體下降時。
例如:為解決 DB 風(fēng)險,引入分布式緩存,只要 2 者不同時掛的時候依然可用。
②弱依賴原則:一定要依賴的,盡可能弱依賴,越弱越好(P)
事物 a 強(qiáng)依賴事物 b,一旦 b 出問題時,那么 a 也會出問題,一損俱損。所以任何強(qiáng)依賴都要盡可能的轉(zhuǎn)化成弱依賴,可以直接降低出問題的概率。
例如:交易核心鏈路在交易成功后要要給用戶發(fā)放積分權(quán)益;交易核心系統(tǒng)需要依賴積分權(quán)益系統(tǒng),好的方式是采用弱依賴,使用異步化的方式,這樣積分權(quán)益系統(tǒng)不可用時,大概率不會影響交易核心鏈路。
③分散原則:雞蛋不要放一個籃子,分散風(fēng)險(R)
打散拆分成 N 份;避免全局只有 1 份,否則一有問題影響范圍就是 100%。
例如:所有交易數(shù)據(jù)都放在同一個庫同一張表里面,萬一這個庫掛了,此時影響所有交易。
例如:將自己所有的錢買了同一只股票,萬一這只股票是樂視就慘了。
④均衡原則:均勻分散風(fēng)險,避免不均衡(R)
最好 N 份中的每份都是均衡的;避免某個份額過大,否則過大的那份一有問題就影響范圍過大了。
例如:xx 應(yīng)用集群有 1000 臺,但由于引流組件 Bug,導(dǎo)致所有流量引到了其中 100 臺上面,導(dǎo)致負(fù)載嚴(yán)重不均衡,最后因負(fù)載無法扛著全面崩潰。類似重大故障已經(jīng)發(fā)生了多次。
例如:將自己所有的錢買了 10 只股票,其中一只占比 99%,萬一這只股票是樂視就慘了。
⑤隔離原則:控制風(fēng)險不擴(kuò)散,不放大(R)
每份之間是相互隔離的;避免一份有問題影響其他的也有問題,傳播擴(kuò)散了影響范圍。
例如:交易數(shù)據(jù)拆分成 10 庫 100 表,但是部署在同一臺物理機(jī)上;萬一某張表有一條大 SQL 把網(wǎng)卡打滿了,那 10 庫 100 表都會受影響。
例如:將自己所有的錢均分買了 10 只股票,每只都占 10%,但 10 只都是樂視系的。
例如:古代赤壁之戰(zhàn)就是一個典型的反面例子,鐵鎖連船導(dǎo)致隔離性被破壞,一把大火燒了 80w 大軍。
隔離是有級別的,隔離級別越高,風(fēng)險傳播擴(kuò)散的難度就越大,容災(zāi)能力越強(qiáng)。
例如:一個應(yīng)用集群由 N 臺服務(wù)器組成,部署在同一臺物理機(jī)上,或同一個機(jī)房的不同物理機(jī)上,或同一個城市的不同機(jī)房里,或不同城市里,不同的部署代表不同的容災(zāi)能力。
例如:人類由無數(shù)人組成,生活在同一個地球的不同洲上,這意味著人類不具備星球級別的隔離能力,當(dāng)?shù)厍虺霈F(xiàn)毀滅性影響時,人類是不具備容災(zāi)的。
隔離原則是一個極其重要的原則,它是前面 4 個原則的前提。
沒有做好隔離,前面 4 個原則都是脆弱的,風(fēng)險很容易傳播擴(kuò)散開,破壞前面 4 個原則的效果。
大量真實系統(tǒng)故障是因為隔離性做得不好導(dǎo)致的,如:線下影響線上,離線影響在線,預(yù)發(fā)影響生產(chǎn),一條爛 SQL 影響整個庫(或整個集群)等等。
分散,均衡,隔離是控制風(fēng)險影響范圍的 3 個核心原則。打散拆分成 N 份,每一份都是均衡的,且相互隔離,一份有問題,影響范圍為 1/N。
⑥無單點原則:要有冗余或其他版本,做到有路可退(T)
快速止血的方式是切換,回滾,擴(kuò)容等;回滾和擴(kuò)容屬于特殊的切換,回滾指的是切換到某個版本,擴(kuò)容指的是將流量切換到新擴(kuò)容的機(jī)器上。
切換得有地方可切才行,所以不能有單點(這里特指強(qiáng)依賴的單點,弱依賴的可以降級),要有冗余備份或其他版本;單點會限制整體的可靠性。
假設(shè)單點的可靠性假設(shè)是 99.99%,它要提升到 99.999% 是非常困難的,但是如果無單點而是依賴 2 個(1 個掛掉沒有關(guān)系,只要不同時掛就行),那整體可靠性就是 99.999999% 會有質(zhì)的提升。
單點故障會導(dǎo)致無法快速止血,拉長整個止血時間,去單點至關(guān)重要。這里的單點不僅僅指的是系統(tǒng)節(jié)點,也包含人員,如訂閱告警的人,應(yīng)急的人等等。
對于(重要)數(shù)據(jù)節(jié)點,必須滿足無單點原則,否則極端情況下可能造成數(shù)據(jù)永久丟失,永遠(yuǎn)無法恢復(fù);(重要)數(shù)據(jù)節(jié)點滿足無單點原則后,保障數(shù)據(jù)一致性比可用性要求更重要。
例如:一個商戶僅支持一個支付渠道,就是典型的單點,萬一這個支付渠道掛了就不能支付了。
例如:一個家庭的所有收入僅依賴父親一個的薪資收入,萬一這個父親病了,就沒有收入了。
無單點原則和分散原則的區(qū)別:
- 當(dāng)節(jié)點無狀態(tài)的情況下,打散拆分成 N 份,每份都是相同的功能,互為冗余,即:節(jié)點無狀態(tài)情況下,分散原則和無單點原則等價,滿足一個即可。
 - 當(dāng)節(jié)點有狀態(tài)的情況下,打散拆分成 N 份,每份都是不相同的,每份都沒有冗余,需要針對每份再做冗余,即:節(jié)點有狀態(tài)情況下,既要滿足分散原則又要滿足單點原則。
 
⑦自我保護(hù)原則:少流血,犧牲一部分,保護(hù)另外一部分(P&R&T)
外部的輸入都不是 100% 可靠的,有時候是無意的錯誤,有時候甚至是惡意的破壞,因此針對外部輸入要有防錯設(shè)計,給自己多一些保護(hù)。
極端情況下可能無法(快速)止血,可以考慮少流血,犧牲一部分保護(hù)另外一部分。例如:限流,降級等。
例如:大促峰值期間,一般會提前降級掉很多功能,同時限流,主要是為了保護(hù)峰值絕大部分人的交易支付體驗。
例如:人體在失血過多或疼痛過度時就會觸發(fā)休克現(xiàn)象,這也是一種典型的自我保護(hù)機(jī)制。
軟件風(fēng)險在何方
前面介紹了控制風(fēng)險的方法,回到軟件系統(tǒng)這個領(lǐng)域,它的風(fēng)險又在哪里?
以軟件系統(tǒng)為對象,從內(nèi)看包括:計算系統(tǒng)和存儲系統(tǒng);從外看包括:人員,硬件,上游系統(tǒng),下游系統(tǒng);以及(隱含的)時間。
由于每個對象都是由其他對象組成的,因此每個對象還可以繼續(xù)往細(xì)分解(理論上可以無限分解下去),上面的分解方式主要是為了簡化理解。
軟件系統(tǒng)風(fēng)險的來源
風(fēng)險源于(有危害的)變化,一個對象的風(fēng)險來源于所有跟它有關(guān)系的對象的(有危害的)變化。
因此,軟件系統(tǒng)風(fēng)險的來源,分為以下 7 大類:
①計算系統(tǒng)變化:運行變慢,運行錯誤
系統(tǒng)運行所依賴的服務(wù)器資源(如 CPU,MEM,IO 等),應(yīng)用資源(RPC 線程數(shù),DB 連接數(shù)等),業(yè)務(wù)資源(業(yè)務(wù) ID 滿了,余額不足,業(yè)務(wù)額度不夠等)的負(fù)載等都會影響系統(tǒng)運行的風(fēng)險期望。
②存儲系統(tǒng)變化:運行變慢,運行錯誤,數(shù)據(jù)錯誤
系統(tǒng)運行所依賴的服務(wù)器資源(如 CPU,MEM,IO 等),存儲資源(并發(fā)數(shù)等),數(shù)據(jù)資源(單庫容量,單表容量等)的負(fù)載和數(shù)據(jù)一致性等都會影響存儲系統(tǒng)運行的風(fēng)險期望。
③人的變化:變更出錯
變更人員的數(shù)量,安全生產(chǎn)意識,熟練程度,變更的數(shù)量,變更的方式等都會影響變更的風(fēng)險期望。
由于變更的人多,變更的次數(shù)也多,導(dǎo)致變更成為螞蟻所有故障來源里的 TOP1,這也是為什么“變更三板斧”這么出名的原因。
“變更三板斧”正確的排序應(yīng)該是“可灰度,可監(jiān)控,可應(yīng)急”;可灰度代表的是 R,可監(jiān)控和可應(yīng)急代表的是 T。
思考:如果變更三板斧讓你再加一板斧,你覺得應(yīng)該是什么?
④硬件變化:損壞
硬件的數(shù)量,質(zhì)量,使用年限,保養(yǎng)等都會影響硬件的風(fēng)險期望,硬件損壞會影響上層軟件系統(tǒng)不可用。
⑤上游變化:請求變大
請求分為 3 個維度:(由無數(shù) API 匯集而成的)網(wǎng)絡(luò)流量,(由無數(shù) KEY 請求組成的)API,KEY。
- 網(wǎng)絡(luò)流量過大會造成網(wǎng)絡(luò)堵塞,影響網(wǎng)絡(luò)通道中的所有網(wǎng)絡(luò)流量請求。
 - API 請求過大會造成對應(yīng)服務(wù)集群過載,影響整個服務(wù)機(jī)器上的所有 API 請求,甚至往外傳播。
 - KEY 請求過大(俗稱“熱點 KEY”)會造成單機(jī)過載,影響單機(jī)上所有 KEY 請求,甚至往外傳播。
 
所以大促保障的時候,不僅僅是關(guān)注核心 API 的容量保障,還需要考慮網(wǎng)絡(luò)流量和熱點 KEY。
⑥下游變化:響應(yīng)變慢,響應(yīng)錯誤
下游服務(wù)的數(shù)量,服務(wù)等級,服務(wù)可用率等影響下游服務(wù)的風(fēng)險期望。下游響應(yīng)變慢可能會拖慢上游,下游響應(yīng)錯誤可能會影響上游運行結(jié)果。
⑦時間變化:時間到期
時間到期往往被人忽視,但它往往具有突然性和全局破壞性,一旦時間到期觸發(fā)故障會導(dǎo)致非常被動,所以要提前識別,盡早預(yù)警,如:秘鑰到期,證書到期,費用到期,跨時區(qū),跨年,跨月,跨日等。
例如:2019 年日本運營商軟銀因證書到期引發(fā) 3000w 用戶長達(dá) 4 小時通信中斷。
以上每一大類風(fēng)險都可以基于 nPRT 公式進(jìn)行逐一分析處理。
風(fēng)險的數(shù)量:一生三,三生萬物
任何一個事物既是由其他事物組成的又是其他事物的組成部分,無限循環(huán)下去;一生三,三生萬物,風(fēng)險的數(shù)量是無窮無盡的。
向內(nèi)看,內(nèi)含內(nèi),可以無限小下去;當(dāng)原子粒度的問題傳播開時,也可能影響軟件系統(tǒng)的可用性,就像 100 納米的新冠病毒就可以影響人體的可用性一樣。
向外看,外有外,可以無限大下去;當(dāng)太陽系毀滅,軟件系統(tǒng)的可用性自然就不復(fù)存在。
雖然風(fēng)險無窮無盡,但是只要我們對風(fēng)險多一些了解,根據(jù)控制風(fēng)險的一些理念和原則,還是可以更好的降低風(fēng)險期望。
談一談敬畏之心:
- 我們對世界的認(rèn)知是有限的,這也讓我們少了許多恐懼,同時也讓我們少了一些敬畏之心。
 - 我們真正要敬畏的不是處罰條例,而是我們不知道的,以及我們不知道我們不知道。
 
結(jié)束語
總結(jié)如下:
- 所有事物都是變化的。
 - 所有事物都不是 100% 可靠的。
 - 因此才有了風(fēng)險,風(fēng)險是不可見的,可見的是故障。
 - 風(fēng)險是不能消滅光的,但是可以遠(yuǎn)離,可以減少。
 - 故障是不可避免的,但是可以推遲,可以縮小影響范圍,縮短影響時間。
 - nPRT 公式不僅僅適用于軟件系統(tǒng)風(fēng)險,也適用于其他風(fēng)險領(lǐng)域,希望對大家有用。
 
作者:樂羊
編輯:陶家龍
出處:轉(zhuǎn)載自公眾號阿里技術(shù)(ID:ali_tech)






















 
 
 








 
 
 
 