雲原生環境下對 “多活” 架構的思考

互聯網公司發展到一定的規模,系統的高可用就變得極其重要。爲了應對那些隨時可能發生的意外,“多活” 在如今互聯網公司好像變得是必備的手段了。甚至一些公司發生一些 P0 事故之後,多活也會出現在 case study 的列表之內。

在雲原生比較流行的今天,很多公司都會選擇某雲服務廠商來部署公司的相關服務。當公司規模較小時,一般情況下公司的架構會像下圖所示。

雖說每個雲服務商都號稱自己的穩定性能達到 N 個 9,但是如果一旦該雲服務商出現比較嚴重的問題時,我們只能祈禱該服務商能趕緊恢復,事後雲服務商發優惠券補償。但是對我們業務的客戶卻造成了很大的傷害,甚者還會造成數據的永久丟失。

當公司的業務達到了一定的規模,一般情況都會再選一個雲服務商形成 “多雲多活” 來保證系統的穩定性、高可用。有幸參與過某公司的雙雲方案的落地,這裏聊聊這種多雲多活的方案的一些思考。

多活爲什麼重要?

這裏就舉兩個實際的例子。

這兩起故障都是比較基礎服務出現的故障導致高可用受損,這個基礎服務的故障一般恢復起來都是比較麻煩,爲了實現高可用,將多活容災推到了解決方案的層面。特別當 B 站故障後,各路文章出來解讀多活,如何實施多活(很多的文章當個樂子看即可)。像這種比較基礎的服務故障,往往恢復時間都是不確定的,多活確實是解決問題的有效手段,能大大提高我們系統的容災能力

服務容災有哪些方案

主備

在比較小點公司內,提起比較多的方案應該是主備方案。這種方案的特點是有一套主、備集羣,正常情況下都只有主集羣在工作,當主集羣出現故障的時候,備用集羣啓用。

這種方案其實不太靠譜,因爲備用集羣正常情況下是不啓用的,所以其代碼,配置,數據都有可能是沒有經過驗證的,萬一真的發生問題時,慌忙啓動的備用集羣大多數情況也是不可用的。

多活

多活就是所有的集羣都是正常提供服務的。正常情況下會按照流量劃分,將流量歸屬到不同的集羣,當某集羣出現問題時,將流量切換到其他集羣正常提供服務。

多活是高可用架構設計的保障,根據多活等級的要求不同,多活還有同城雙活,異地雙活,兩地三中心,三地五中心等。對多活的要求越高,投入的資源也就會越高。這裏就不再詳細講述這些名字背後的技術細節了。

多雲多活的技術細節

多雲多活指的是公司選擇兩家雲服務商,將服務部署兩個雲上,正常情況兩個雲同時對外提供服務,當其中一個雲出現問題時,將流量全都切換到另外一個雲。

這個圖基本是大多數公司部署多雲多活的技術方案,下面聊聊這個方案的相關技術細節和缺點。

這個架構的大概流程:

流量分發 / 切換

分佈在不同的兩個雲的集羣的系統承載能力是需要經過評估的,流量接入層按照系統承載能力的差異,將流量按照不同的比例進行分發。不過一般情況下,兩個雲的系統會盡量保證系統的承載能力是一致的,所以流量是平分到兩個集羣中。

當某個雲發生故障的時候,在流量接入層會將流量全部切換到另外一個雲上,保證另外一個雲的故障不會用戶造成影響。由此可見流量接入的層的重要性,不過這一層組件比較成熟,在我經歷的項目中,這一層確實沒有發生過故障。

業務層雙活

業務層對於雙雲雙活來說,其實比較簡單的,就是將同樣的代碼分別部署到兩個雲即可。

但是要注意的是,這一層是有 IDC 之分的,要保證的是 雲 1  的服務不能訪問到 雲 2 去,對於開發人員來說也不用太擔心,只要配置不出錯,一般業務框架會保證這個事情。

再扯一點其他的,業務層正常情況下會根據業務需求快速迭代,這就給業務系統帶來了不穩定性。如果 CI/CD 做的好的話,能夠讓業務做到快速回滾,但是這也會給核心業務造成一定的影響。爲了解決這個問題,需要將核心業務進行隔離,讓新上線的業務在非核心集羣進行驗證,等待穩定後再部署到核心集羣。

存儲層

先提出一個問題:存儲層這樣設計是否有問題?

這個設計還是蠻普遍的,比如 《鬥魚基於 etcd 和 ZooKeeper 的註冊中心實踐案例》這篇文章中,對於存儲基本也是這樣設計的。

redis、mysql 還是選擇經典的一主多從的設計方式。

優點

架構簡單,可以利用 redis、mysql 自身的機制進行數據同步,讓數據的訪問在各自的雲進行。

缺點

其實缺點一眼就看出來了,這整個 “雙雲雙活” 的設計的缺點太依賴於主節點所在的雲的穩定性和專線的穩定性。

在我經歷的項目,雲的穩定性還是可以的,最容易出現問題的其實這條專線,比如:專線被打滿。當專線出現問題時,研發只能傻樂,等待運維恢復專線,如何保證這個專線的穩定性成爲這個架構最重要的事情。

當然另外一個問題也是很難解決:主節點所在的雲或者專線發生故障的時候,整個項目其實也就癱瘓了大半。

因爲當主節點所在的雲出現故障時,在流量接入層可以將流量切換到另外一個集羣,但是我們的主業務肯定不是” 只讀 “的,肯定還有寫業務存在, 於是出現故障的時候,只能看到一堆堆的寫失敗報警,有些業務接口肯定也在報錯,只能等待故障恢復後,人工補償這些寫失敗的數據。

所以爲了解決這個系統設計的缺陷,就是要將 redis/mysql 做成多主多從,主與主集羣之間做數據同步。這個方案說起來容易,但是實踐起來就太困難了。

這裏只使用 mysql/redis 作爲示例來解釋雙雲雙活,其實我們的系統還有另外一些分佈式一致性系統如:ectd,讀者可以考慮一下如何部署到雙雲上面。

結論

其實很多的公司的多活最終都因爲各種原因淪爲了 “僞多活”。 非雲,非 BAT 級別的廠,一般建義先做到核心數據 (交易,用戶) 多中心備份,畢竟不是每次火災水災都能趕上,當某雲出現問題時可以快速恢復,這纔是重中之重。

上面提高的 “雙雲雙活” 方案的瓶頸就在於存儲層,讓整個集羣處於 “僞多活” 的狀態。這個方案確實能解決一些問題,但是高可用並沒有想象中的那麼出色,更多時候這樣項目一般都淪落成某些人晉升的 KPI。

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