云原生环境下对“多活”架构的思考
互聯網公司發展到一定的規模,系統的高可用就變得極其重要。為了應對那些隨時可能發生的意外,“多活”在如今互聯網公司好像變得是必備的手段了。甚至一些公司發生一些 P0 事故之后,多活也會出現在 case study 的列表之內。
在云原生比較流行的今天,很多公司都會選擇某云服務廠商來部署公司的相關服務。當公司規模較小時,一般情況下公司的架構會像下圖所示。
雖說每個云服務商都號稱自己的穩定性能達到 N 個 9,但是如果一旦該云服務商出現比較嚴重的問題時,我們只能祈禱該服務商能趕緊恢復,事后云服務商發優惠券補償。但是對我們業務的客戶卻造成了很大的傷害,甚者還會造成數據的永久丟失。
當公司的業務達到了一定的規模,一般情況都會再選一個云服務商形成“多云多活”來保證系統的穩定性、高可用。有幸參與過某公司的雙云方案的落地,這里聊聊這種多云多活的方案的一些思考。
多活為什么重要?
這里就舉兩個實際的例子。
2021年7月13日,B 站部分服務器機房發生故障,整個故障持續超過一小時。
2021年10月9日,富途證券的 IDC 機房網絡故障事件導致某些客戶資產清零、無法交易。
這兩起故障都是比較基礎的服務出現的故障導致高可用受損,這個基礎服務的故障一般恢復起來都是比較麻煩,為了實現高可用,將多活容災推到了解決方案的層面。特別當 B 站故障后,各路文章出來解讀多活,如何實施多活(很多的文章當個樂子看即可)。像這種比較基礎的服務故障,往往恢復時間都是不確定的,多活確實是解決問題的有效手段,能大大提高我們系統的容災能力。
服務容災有哪些方案
主備
在比較小點公司內,提起比較多的方案應該是主備方案。這種方案的特點是有一套主、備集群,正常情況下都只有主集群在工作,當主集群出現故障的時候,備用集群啟用。
這種方案其實不太靠譜,因為備用集群正常情況下是不啟用的,所以其代碼,配置,數據都有可能是沒有經過驗證的,萬一真的發生問題時,慌忙啟動的備用集群大多數情況也是不可用的。
多活
多活就是所有的集群都是正常提供服務的。正常情況下會按照流量劃分,將流量歸屬到不同的集群,當某集群出現問題時,將流量切換到其他集群正常提供服務。
多活是高可用架構設計的保障,根據多活等級的要求不同,多活還有同城雙活,異地雙活,兩地三中心,三地五中心等。對多活的要求越高,投入的資源也就會越高。這里就不再詳細講述這些名字背后的技術細節了。
多云多活的技術細節
多云多活指的是公司選擇兩家云服務商,將服務部署兩個云上,正常情況兩個云同時對外提供服務,當其中一個云出現問題時,將流量全都切換到另外一個云。
這個圖基本是大多數公司部署多云多活的技術方案,下面聊聊這個方案的相關技術細節和缺點。
這個架構的大概流程:
客戶端通過接入層訪問系統相關服務
接入層根據流量分發規則,將流量向下分發到業務層
業務層經過相關的業務邏輯處理,將相關數據寫入到相關的存儲中
流量分發/切換
分布在不同的兩個云的集群的系統承載能力是需要經過評估的,流量接入層按照系統承載能力的差異,將流量按照不同的比例進行分發。不過一般情況下,兩個云的系統會盡量保證系統的承載能力是一致的,所以流量是平分到兩個集群中。
當某個云發生故障的時候,在流量接入層會將流量全部切換到另外一個云上,保證另外一個云的故障不會用戶造成影響。由此可見流量接入的層的重要性,不過這一層組件比較成熟,在我經歷的項目中,這一層確實沒有發生過故障。
業務層雙活
業務層對于雙云雙活來說,其實比較簡單的,就是將同樣的代碼分別部署到兩個云即可。
但是要注意的是,這一層是有 IDC 之分的,要保證的是云1 的服務不能訪問到云2 去,對于開發人員來說也不用太擔心,只要配置不出錯,一般業務框架會保證這個事情。
再扯一點其他的,業務層正常情況下會根據業務需求快速迭代,這就給業務系統帶來了不穩定性。如果 CI/CD 做的好的話,能夠讓業務做到快速回滾,但是這也會給核心業務造成一定的影響。為了解決這個問題,需要將核心業務進行隔離,讓新上線的業務在非核心集群進行驗證,等待穩定后再部署到核心集群。
存儲層
先提出一個問題:存儲層這樣設計是否有問題?
這個設計還是蠻普遍的,比如 《斗魚基于etcd和ZooKeeper的注冊中心實踐案例》
redis、mysql 還是選擇經典的一主多從的設計方式。
選擇一個 “云” 將 mysql/redis 的主節點和部分從節點部署到這個云上
將 mysql/redis 其他的從節點部署到另外一個云上
redis/mysql 之間利用主從同步機制進行數據同步
云1 和 云2 之間由一條專線連接
優點
架構簡單,可以利用 redis、mysql 自身的機制進行數據同步,讓數據的訪問在各自的云進行。
缺點
其實缺點一眼就看出來了,這整個“雙云雙活”的設計的缺點太依賴于主節點所在的云的穩定性和專線的穩定性。
在我經歷的項目,云的穩定性還是可以的,最容易出現問題的其實這條專線,比如:專線被打滿。當專線出現問題時,研發只能傻樂,等待運維恢復專線,如何保證這個專線的穩定性成為這個架構最重要的事情。
當然另外一個問題也是很難解決:主節點所在的云或者專線發生故障的時候,整個項目其實也就癱瘓了大半。
因為當主節點所在的云出現故障時,在流量接入層可以將流量切換到另外一個集群,但是我們的主業務肯定不是”只讀“的,肯定還有寫業務存在, 于是出現故障的時候,只能看到一堆堆的寫失敗報警,有些業務接口肯定也在報錯,只能等待故障恢復后,人工補償這些寫失敗的數據。
所以為了解決這個系統設計的缺陷,就是要將 redis/mysql 做成多主多從,主與主集群之間做數據同步。這個方案說起來容易,但是實踐起來就太困難了。
這里只使用 mysql/redis 作為示例來解釋雙云雙活,其實我們的系統還有另外一些分布式一致性系統如:ectd,讀者可以考慮一下如何部署到雙云上面。
結論
其實很多的公司的多活最終都因為各種原因淪為了“偽多活”。 非云,非BAT級別的廠,一般建義先做到核心數據(交易,用戶)多中心備份,畢竟不是每次火災水災都能趕上,當某云出現問題時可以快速恢復,這才是重中之重。
上面提高的“雙云雙活”方案的瓶頸就在于存儲層,讓整個集群處于“偽多活”的狀態。這個方案確實能解決一些問題,但是高可用并沒有想象中的那么出色,更多時候這樣項目一般都淪落成某些人晉升的 KPI。
寫文章不易請大家幫忙點擊 在看,點贊,分享。
總結
以上是生活随笔為你收集整理的云原生环境下对“多活”架构的思考的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Goland 这些实操技巧,你可能还不会
- 下一篇: Go 如何利用 Linux 内核的负载均