高可用係統常用解決手段淺述
所謂可用性,是指 某係統能夠提供正常服務的特性。
可用性的高低是使用不可用時間占總時間的比例來衡量。不可用時間是從故障發生到故障恢複的時間。 比如,可用性 4 個 9 的係統(99.99%),它一年宕機時間不能超過53分鍾(=365*24*60*(1-0.9999)) 。 做到高可用係統,需要盡可能的降低故障發生的次數和減少故障持續的時間。
出現係統不可用的原因,一種是人為的,比如發布了有 bug 的代碼、不規範的發布流程導致的宕機或者網站訪問量過載造成的雪崩等;另一種則是非人為的,由於外部係統和環境的變化造成的,比如硬盤老化造成的故障、機房斷電、電纜中斷等。我們需要在複雜的外部環境下保證係統的高可用。以下總結了常用的高可用解決手段。
1 拆分
這類解決手段不是以減少不可用時間為目的,而是以減少故障影響麵為目的。因為一個大的係統拆分成了幾個小的獨立模塊,一個模塊出了問題不會影響到其他的模塊,從而降低故障的影響麵。手段包括:
1.1 水平拆分
係統水平拆分成三層:接入層,服務層和數據存儲層。將有狀態和無狀態的劃分開來,接入層和服務層設計成無狀態的,存儲層是有狀態的。無狀態層的服務可以平行擴展,請求落到哪台服務器都沒有關係。平行擴展也有利於係統容量的擴充,快速擴容應對突然爆發流量的衝擊。
1.2 垂直拆分
根據功能垂直劃分,拆成相對獨立的模塊。有的僅是服務層做了拆分,存儲層共用。更為徹底的是,拆分與該係統的業務領域模型關聯,一個領域模型劃分成一個模塊。在數據庫層麵,還可以分庫分表拆分,這樣一個庫的損壞,不會影響到其他庫。分庫分表需要增加路由邏輯,及保證路由規則的一致性。
1.3 讀寫分離
也屬於垂直拆分的一種。寫請求的依賴主庫,讀請求的依賴備庫。這樣做,當出現故障的時候,可以隻有讀請求的流量,寫服務暫時關閉,從而減少了故障的影響麵。但需要關注數據一致性的問題。
2 降級
這類手段不是為了避免故障的發生,而是當故障發生後,怎麼減小故障所造成的損失。比如,係統正常時提供的服務能力是 100%,出現係統故障後,我們有措施能讓係統服務能力不直接降到了 0,而是還能提供 50% 的服務能力。
2.1 限流
限流,流量控製。當請求量超過係統的最大容量後,訪問延遲就會增加,超過峰值的流量會拖累整個係統,出現宕機。因此,需要提前流量控製,對於超過峰值的流量,可以直接拒絕掉或者隨機選擇拒絕。限流結合業務自定義配置,優先保證核心服務的正常響應,非核心服務可直接關閉。
2.2 異步調用
係統進行拆分之後,會分成多個模塊。模塊之間的依賴有強弱之分。如果是強依賴的,那麼如果依賴方出問題了,也會受到牽連出問題。這時可以梳理整個流程的調用關係,做成弱依賴調用。弱依賴調用通過消息中間件的方式來實現。
異步調用不關心返回結果,不會傳遞依賴方的錯誤,進而避免造成更大規模的不可用。
2.3 同步調用合理設置超時時間
對於不能異步化的,采用同步調用,需要注意設置合理的超時時間。過長的超時,會延遲結果等待時間,導致整體的鏈路調用時間延長,降低整體的QPS。
經驗值:超時時間設置成平均響應延遲的2倍。
2.4 失敗重試
要區分調用失敗的類型。有些失敗是短暫偶然的(比如網絡抖動),進行重試即可。而有些失敗是確定,那麼重試反而會造成調用請求量的放大,加重對調用係統的負擔。
經驗值:重試的次數一般設為3次,再多次的重試沒有好處。
2.5 兜底方案
在係統真的出現了不可用的時候,需要有兜底方案。比如一些提示安撫用戶,或者有跳轉鏈接轉移用戶的請求。
3 冗餘
冗餘,目的是避免單點故障。比如對於接入層和服務層,可以平行擴展機器部署,這樣一台機器宕機,可以將請求轉移到其他機器。數據層的冗餘比較複雜,增加一份備份數據,需要考慮一致性的問題。按照分布式係統的 CAP 理論三者不可用同時滿足的原理,為了滿足可用性和分區容錯性,就必須犧牲一致性,因此考慮使用弱一致性、最終一致性的解決方案來解決(此類文章很多,略)。
冗餘備份有全量和增量之分,有熱備和冷備之分。冗餘可以是兩台機器的主備冗餘,可以是多機的集群式冗餘。從部署來看,可以是跨機架、跨機房到跨城的備份。多機複製部署,上層調用采用負載均衡策略,還需要注意負載均衡設備的單點問題。
失敗通知和失敗切換
當集群機器某台機器出現了故障,或者某個進程掛了,能夠快速的發現,並且告警通知出來。路由選擇器能快速的切除掉這台機器,當恢複後又能自動的加入回來。
4 灰度發布
有個觀點,單點和發布是可用性最大的敵人。線網出現了故障,查故障的原因,一個常用的辦法就是追查下最近是否有發過版本,比較下發布前後的代碼。
使用灰度發布策略,發布並且驗證沒問題後再全量發布。灰度發布的策略,包括搭建預發布環境,有專用的預發布機器;或者路由策略先摘除灰度發布的機器,驗證正常後再加入該機器;或者采用UIN取模灰度策略,驗證沒問題後再取消灰度策略。盡量采用自動化發布,減少人為發布的流程。盡量選擇在訪問量低峰時段升級,減小影響用戶群。
回滾機製
出現問題後,能有有效的回滾機製。涉及到數據修改的,發布後會引起髒數據的寫入,需要有可靠的回滾流程,保證髒數據的清除。
除了發布流程外,還應該在其他開發流程上做規範,比如代碼控製,集成編譯、自動化測試、靜態代碼掃描等。
5 切換
切換之前需要做好監控。監控應該是貫穿於上述所有手段的。比如業務某個模塊訪問量要監控,依賴的調用方出問題要監控,某個機房故障了要監控,發布了服務要監控等。監控既包括係統層麵的(比如CPU、內存、網絡、IO、進程),還包括業務層麵的(請求量、錯誤率、耗時)。監控的間隔需要支持到分鍾級甚至到秒級的。
監控不是目的,監控沒法保證高可用,切換才是目的,從故障的係統切換到正常的係統才能保證可用性。比如監控某台機器硬盤出問題了,那麼會告警出來,然後使用一台新的機器替換。
切換可以是自動的,也可以是人工的。人工切換會有延遲恢複的問題,但能做到準確。自動切換,會比較快速,但必須要確保切換源是正常的,否則可能會引起更加嚴重的事故。切換後,要有實時的效果反饋。
原文發布時間為:2017-04-05
本文來自雲棲社區合作夥伴“Linux中國”
最後更新:2017-05-23 15:03:28