終於有人把 "高可用" 說清楚了!

參考  https://baijiahao.baidu.com/s?id=1692367278967046308&wfr=spider&for=pc    

https://www.sohu.com/a/452453360_463994

 

我是樂羊,一個熱愛風險防控的人,之前參與過螞蟻 Glocal 多個站點從 0 到 1 的建站和高可用建設,目前正在參與螞蟻大安全的高可用建設。

無論是一個域,一個 BG,還是一個站點,雖然範圍有大有小,對象有所不同,但其高可用的理念都是相通的,今天將自己對高可用的一點點思考以及總結的“nPRT 公式”分享給大家。

本文采用“高可用是什麼,爲什麼要高可用,怎麼做高可用,爲什麼這麼做,軟件風險又在哪裏”的邏輯來介紹。

高可用是一種控制風險的能力

高可用是一種面向風險設計,使系統具備控制風險,提供更高的可用性的能力。

爲什麼要高可用

對於一個公司而言,“爲什麼要高可用”可以完整理解爲“公司爲什麼要(做系統)高可用”。

以公司爲對象,從內看包括:人,軟件(物),硬件(物);從外看包括:客戶,股東,社會;從自身看包括:公司。

高可用的大前提,所有事物都不是 100% 可靠的:

  • 所有事物都是變化的(唯一不變的是變化)。
  • 所有變化的都不是 100% 可靠的。
  • 結論:所有事物都不是 100% 可靠的。

內因,人、物都不是 100% 可靠的

  • 從人的層面: 人都是有可能犯錯的。
  • 從軟件層面: 軟件都是有可能有 Bug 的。
  • 從硬件層面: 硬件都是有可能會壞的。

從概率學角度分析,凡是有可能會出錯的,只要變化次數足夠多,最終出錯的概率會無限趨向於 1。

外因,無高可用,對外影響面是很大的

  • 從客戶角度:無高可用,客戶服務可能會中斷。
  • 從股東層面:無高可用,股價可能會下跌。
  • 從社會角度:無高可用,社會秩序可能受影響。

根因(本質):控制風險。

從公司自身角度:控制風險,保障公司價值,避免傷及根本。

如何做高可用

如何做高可用,本質上就是:如何控制風險。

風險相關概念

風險:指未來會發生危害的一種可能性,但實際未發生,記爲r。

故障:指已發生或正在發生危害的一種事實,是風險變現實的結果。

風險概率:指一個風險變故障的概率。用它來表示風險觸發爲故障的難易程度,記爲 P(r)。

故障影響範圍:指在單位時間內,一個故障造成的危害影響,記爲 R(r)。

故障影響時長:指一個故障持續的時間,記爲 T(r)。

故障影響面:指一個故障影響範圍乘以故障影響時長的總和。這裏用故障影響面來表示故障總的危害程度,記爲 F(r)。

風險期望:指每個風險變故障的概率乘以每個風險變故障後的故障影響面的總和。這裏用風險期望來表示風險的潛在危害程度,記爲 E(r)。

風險期望的公式

根據上節的定義,可以推導出風險期望的公式如下:

r 代表風險,風險期望會隨着風險的數量 n 和每個風險的 P、R、T 下降而下降,簡稱 nPRT 公式。(注:如果要引用該公式請註明出處。)

控制風險的 4 大因素(nPRT)

①減少風險數量,n

從源頭遠離風險,做到與風險載體無連接,無關係;那麼該風險概率就是0,也不關心該風險發生後的故障影響面是大是小,完全不關心。

例如:重大節日活動,施行全站封網,變更的數量就會得到一個明顯的下降,就是典型的減少風險數量。

例如:系統 A 完全不依賴 Oracle,那系統 A 就不用關心 Oracle 的任何風險,哪怕美國總統突然緊急宣佈 Oracle 立即立刻禁止在中國使用,系統 A 也無所謂。

例如:最近新冠大流行,人傳人很可怕,如果你今天選擇不上班不出門,那你今天就不用擔心被外面的行人和同事傳染。

②降低風險變故障的概率(即:增加風險變故障的難度),P

把風險當成一個對象看待,給它層層設卡,增加風險變故障的門檻和難度,不要再讓“不小心多了一個空格或字符,系統就掛了”這種慘案輕易出現。

例如:人員 B 要對系統 C 進行變更,可以對人員 B 增加變更認證考試,對變更內容要求線下(或仿真)測試,對變更內容進行 CR,系統 C 提供變更效果預覽能力(類似監控模式或試運行)。

萬一人員 B 想惡意變更搞破壞,還可以增加非同人複覈,系統C可以增加防錯設計進行保護等等。

例如:以新冠爲例,帶口罩,勤洗手,多通風等就可以降低染上新冠的概率。

③減小故障影響範圍,R

以大拆小,將一個整體拆分成 N 個小的個體,每個個體之間進行相互隔離,單個個體出問題僅影響單個個體,實現小而美。

例如:分佈式架構就是這個的典範,集中式一損俱損,分佈式一損即 N 分之一損。

例如:以新冠爲例,網格化管理,各省或市間的流動進行限制,跨省必須核酸+隔離 14 天,有效控制新冠的傳播範圍。

④縮短故障影響時長,T

故障影響時長由故障發現時間和故障止血時間決定,所以要早發現早止血。

發現方式分爲:事前的預警,事後的告警。儘可能朝事前預警去做,給止血爭取時間甚至將風險扼殺在搖籃中。

止血方式分爲:切換,回滾,擴容,降級 or 限流,BUG 修復等。故障出現時第一優先原則爲快速止血(如切換、回滾、擴容),嚴禁去定位根因;當無法快速止血時以少流血爲第二優先原則,如降級、限流。

止血效率:自動 vs 人工 ;一鍵化 vs 多步操作。儘可能用自動化去代替人工操作,若人工操作時儘量實現一鍵化,提升止血速度。

例如:對於容量水位,可以在警戒線之前劃一條預警線,提前預警,從容應對。

例如:分佈式應用集羣,任何一臺應用服務器有問題時,負載均衡會通過心跳檢查自動把有問題的應用服務器剔除,將請求轉發給其他(熱)備份冗餘的服務器上。

例如:以新冠爲例,但由於每個生命都是獨一無二的,沒有辦法切換,也沒有辦法回滾,也不能降級(涉及人道主義),只能對症下藥慢慢治療。

高可用架構設計的 7 大核心原則

根據 nPRT 公式,在高可用架構設計時有以下 7 個核心原則:

①少依賴原則:能不依賴的,儘可能不依賴,越少越好(n)

由於所有事物都不是 100% 可靠的,當 2 個事物之間有了關係,那麼就會相互影響,就互爲對方的一個風險,一個出問題可能會影響另外一個。我們統一用依賴來泛指這裏的“關係”。

例如:一個系統同時依賴 Oracle,MySQL,OB 三種關係型數據庫,少依賴原則是改成僅依賴最成熟穩定的 OB,不依賴 Oracle 和 MySQL。

什麼場景適合多依賴?當引入依賴(n 變大)可以減小 PRT 中的一個或多個,且使 E(r) 整體下降時。

例如:爲解決 DB 風險,引入分佈式緩存,只要 2 者不同時掛的時候依然可用。

②弱依賴原則:一定要依賴的,儘可能弱依賴,越弱越好(P)

事物 a 強依賴事物 b,一旦 b 出問題時,那麼 a 也會出問題,一損俱損。所以任何強依賴都要儘可能的轉化成弱依賴,可以直接降低出問題的概率。

例如:交易核心鏈路在交易成功後要要給用戶發放積分權益;交易核心系統需要依賴積分權益系統,好的方式是採用弱依賴,使用異步化的方式,這樣積分權益系統不可用時,大概率不會影響交易核心鏈路。

③分散原則:雞蛋不要放一個籃子,分散風險(R)

打散拆分成 N 份;避免全局只有 1 份,否則一有問題影響範圍就是 100%。

例如:所有交易數據都放在同一個庫同一張表裏面,萬一這個庫掛了,此時影響所有交易。

例如:將自己所有的錢買了同一只股票,萬一這隻股票是樂視就慘了。

④均衡原則:均勻分散風險,避免不均衡(R)

最好 N 份中的每份都是均衡的;避免某個份額過大,否則過大的那份一有問題就影響範圍過大了。

例如:xx 應用集羣有 1000 臺,但由於引流組件 Bug,導致所有流量引到了其中 100 臺上面,導致負載嚴重不均衡,最後因負載無法扛着全面崩潰。類似重大故障已經發生了多次。

例如:將自己所有的錢買了 10 只股票,其中一隻佔比 99%,萬一這隻股票是樂視就慘了。

⑤隔離原則:控制風險不擴散,不放大(R)

每份之間是相互隔離的;避免一份有問題影響其他的也有問題,傳播擴散了影響範圍。

例如:交易數據拆分成 10 庫 100 表,但是部署在同一臺物理機上;萬一某張表有一條大 SQL 把網卡打滿了,那 10 庫 100 表都會受影響。

例如:將自己所有的錢均分買了 10 只股票,每隻都佔 10%,但 10 只都是樂視系的。

例如:古代赤壁之戰就是一個典型的反面例子,鐵鎖連船導致隔離性被破壞,一把大火燒了 80w 大軍。

隔離是有級別的,隔離級別越高,風險傳播擴散的難度就越大,容災能力越強。

例如:一個應用集羣由 N 臺服務器組成,部署在同一臺物理機上,或同一個機房的不同物理機上,或同一個城市的不同機房裏,或不同城市裏,不同的部署代表不同的容災能力。

例如:人類由無數人組成,生活在同一個地球的不同洲上,這意味着人類不具備星球級別的隔離能力,當地球出現毀滅性影響時,人類是不具備容災的。

隔離原則是一個極其重要的原則,它是前面 4 個原則的前提。

沒有做好隔離,前面 4 個原則都是脆弱的,風險很容易傳播擴散開,破壞前面 4 個原則的效果。

大量真實系統故障是因爲隔離性做得不好導致的,如:線下影響線上,離線影響在線,預發影響生產,一條爛 SQL 影響整個庫(或整個集羣)等等。

分散,均衡,隔離是控制風險影響範圍的 3 個核心原則。打散拆分成 N 份,每一份都是均衡的,且相互隔離,一份有問題,影響範圍爲 1/N。

⑥無單點原則:要有冗餘或其他版本,做到有路可退(T)

快速止血的方式是切換,回滾,擴容等;回滾和擴容屬於特殊的切換,回滾指的是切換到某個版本,擴容指的是將流量切換到新擴容的機器上。

切換得有地方可切纔行,所以不能有單點(這裏特指強依賴的單點,弱依賴的可以降級),要有冗餘備份或其他版本;單點會限制整體的可靠性。

對於(重要)數據節點,必須滿足無單點原則,否則極端情況下可能造成數據永久丟失,永遠無法恢復;(重要)數據節點滿足無單點原則後,保障數據一致性比可用性要求更重要。

例如:一個商戶僅支持一個支付渠道,就是典型的單點,萬一這個支付渠道掛了就不能支付了。

例如:一個家庭的所有收入僅依賴父親一個的薪資收入,萬一這個父親病了,就沒有收入了。

無單點原則和分散原則的區別:

  • 當節點無狀態的情況下, 打散拆分成 N 份,每份都是相同的功能,互爲冗餘,即:節點無狀態情況下,分散原則和無單點原則等價,滿足一個即可。
  • 當節點有狀態的情況下, 打散拆分成 N 份,每份都是不相同的,每份都沒有冗餘,需要針對每份再做冗餘,即:節點有狀態情況下,既要滿足分散原則又要滿足單點原則。

⑦自我保護原則:少流血,犧牲一部分,保護另外一部分(P&R&T)

外部的輸入都不是 100% 可靠的,有時候是無意的錯誤,有時候甚至是惡意的破壞,因此針對外部輸入要有防錯設計,給自己多一些保護。

極端情況下可能無法(快速)止血,可以考慮少流血,犧牲一部分保護另外一部分。例如:限流,降級等。

例如:大促峯值期間,一般會提前降級掉很多功能,同時限流,主要是爲了保護峯值絕大部分人的交易支付體驗。

例如:人體在失血過多或疼痛過度時就會觸發休克現象,這也是一種典型的自我保護機制。

軟件風險在何方

前面介紹了控制風險的方法,回到軟件系統這個領域,它的風險又在哪裏?

以軟件系統爲對象,從內看包括:計算系統和存儲系統;從外看包括:人員,硬件,上游系統,下游系統;以及(隱含的)時間。

由於每個對象都是由其他對象組成的,因此每個對象還可以繼續往細分解(理論上可以無限分解下去),上面的分解方式主要是爲了簡化理解。

軟件系統風險的來源

風險源於(有危害的)變化,一個對象的風險來源於所有跟它有關係的對象的(有危害的)變化。

因此,軟件系統風險的來源,分爲以下 7 大類:

①計算系統變化:運行變慢,運行錯誤

系統運行所依賴的服務器資源(如 CPU,MEM,IO 等),應用資源(RPC 線程數,DB 連接數等),業務資源(業務 ID 滿了,餘額不足,業務額度不夠等)的負載等都會影響系統運行的風險期望。

②存儲系統變化:運行變慢,運行錯誤,數據錯誤

系統運行所依賴的服務器資源(如 CPU,MEM,IO 等),存儲資源(併發數等),數據資源(單庫容量,單表容量等)的負載和數據一致性等都會影響存儲系統運行的風險期望。

③人的變化:變更出錯

變更人員的數量,安全生產意識,熟練程度,變更的數量,變更的方式等都會影響變更的風險期望。

由於變更的人多,變更的次數也多,導致變更成爲螞蟻所有故障來源裏的 TOP1,這也是爲什麼“變更三板斧”這麼出名的原因。

“變更三板斧”正確的排序應該是“可灰度,可監控,可應急”;可灰度代表的是 R,可監控和可應急代表的是 T。

思考:如果變更三板斧讓你再加一板斧,你覺得應該是什麼?

④硬件變化:損壞

硬件的數量,質量,使用年限,保養等都會影響硬件的風險期望,硬件損壞會影響上層軟件系統不可用。

⑤上游變化:請求變大

請求分爲 3 個維度:(由無數 API 彙集而成的)網絡流量,(由無數 KEY 請求組成的)API,KEY。

  • 網絡流量過大會造成網絡堵塞,影響網絡通道中的所有網絡流量請求。
  • API 請求過大會造成對應服務集羣過載,影響整個服務機器上的所有 API 請求,甚至往外傳播。
  • KEY 請求過大(俗稱“熱點 KEY”)會造成單機過載,影響單機上所有 KEY 請求,甚至往外傳播。

所以大促保障的時候,不僅僅是關注核心 API 的容量保障,還需要考慮網絡流量和熱點 KEY。

⑥下游變化:響應變慢,響應錯誤

下游服務的數量,服務等級,服務可用率等影響下游服務的風險期望。下游響應變慢可能會拖慢上游,下游響應錯誤可能會影響上游運行結果。

⑦時間變化:時間到期

例如:2019 年日本運營商軟銀因證書到期引發 3000w 用戶長達 4 小時通信中斷。

以上每一大類風險都可以基於 nPRT 公式進行逐一分析處理。

風險的數量:一生三,三生萬物

任何一個事物既是由其他事物組成的又是其他事物的組成部分,無限循環下去;一生三,三生萬物,風險的數量是無窮無盡的。

向內看,內含內,可以無限小下去;當原子粒度的問題傳播開時,也可能影響軟件系統的可用性,就像 100 納米的新冠病毒就可以影響人體的可用性一樣。

向外看,外有外,可以無限大下去;當太陽系毀滅,軟件系統的可用性自然就不復存在。

雖然風險無窮無盡,但是隻要我們對風險多一些瞭解,根據控制風險的一些理念和原則,還是可以更好的降低風險期望。

談一談敬畏之心:

  • 我們對世界的認知是有限的,這也讓我們少了許多恐懼,同時也讓我們少了一些敬畏之心。
  • 我們真正要敬畏的不是處罰條例,而是我們不知道的,以及我們不知道我們不知道。

結束語

總結如下:

  • 所有事物都是變化的。
  • 所有事物都不是 100% 可靠的。
  • 因此纔有了風險,風險是不可見的,可見的是故障。
  • 風險是不能消滅光的,但是可以遠離,可以減少。
  • 故障是不可避免的,但是可以推遲,可以縮小影響範圍,縮短影響時間。

nPRT 公式不僅僅適用於軟件系統風險,也適用於其他風險領域,希望對大家有用。

作者:樂羊

編輯:陶家龍

出處:轉載自公衆號阿里技術(ID:ali_tech)

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