云原生環(huán)境下對“多活”架構(gòu)的思考
互聯(lián)網(wǎng)公司發(fā)展到一定的規(guī)模,系統(tǒng)的高可用就變得極其重要。為了應(yīng)對那些隨時可能發(fā)生的意外,“多活”在如今互聯(lián)網(wǎng)公司好像變得是必備的手段了。甚至一些公司發(fā)生一些 P0 事故之后,多活也會出現(xiàn)在 case study 的列表之內(nèi)。
在云原生比較流行的今天,很多公司都會選擇某云服務(wù)廠商來部署公司的相關(guān)服務(wù)。當(dāng)公司規(guī)模較小時,一般情況下公司的架構(gòu)會像下圖所示。

雖說每個云服務(wù)商都號稱自己的穩(wěn)定性能達(dá)到 N 個 9,但是如果一旦該云服務(wù)商出現(xiàn)比較嚴(yán)重的問題時,我們只能祈禱該服務(wù)商能趕緊恢復(fù),事后云服務(wù)商發(fā)優(yōu)惠券補(bǔ)償。但是對我們業(yè)務(wù)的客戶卻造成了很大的傷害,甚者還會造成數(shù)據(jù)的永久丟失。
當(dāng)公司的業(yè)務(wù)達(dá)到了一定的規(guī)模,一般情況都會再選一個云服務(wù)商形成“多云多活”來保證系統(tǒng)的穩(wěn)定性、高可用。有幸參與過某公司的雙云方案的落地,這里聊聊這種多云多活的方案的一些思考。
多活為什么重要?
這里就舉兩個實際的例子。
2021年7月13日,B 站部分服務(wù)器機(jī)房發(fā)生故障,整個故障持續(xù)超過一小時。 2021年10月9日,富途證券的 IDC 機(jī)房網(wǎng)絡(luò)故障事件導(dǎo)致某些客戶資產(chǎn)清零、無法交易。
這兩起故障都是比較基礎(chǔ)的服務(wù)出現(xiàn)的故障導(dǎo)致高可用受損,這個基礎(chǔ)服務(wù)的故障一般恢復(fù)起來都是比較麻煩,為了實現(xiàn)高可用,將多活容災(zāi)推到了解決方案的層面。特別當(dāng) B 站故障后,各路文章出來解讀多活,如何實施多活(很多的文章當(dāng)個樂子看即可)。像這種比較基礎(chǔ)的服務(wù)故障,往往恢復(fù)時間都是不確定的,多活確實是解決問題的有效手段,能大大提高我們系統(tǒng)的容災(zāi)能力。
服務(wù)容災(zāi)有哪些方案
主備
在比較小點公司內(nèi),提起比較多的方案應(yīng)該是主備方案。這種方案的特點是有一套主、備集群,正常情況下都只有主集群在工作,當(dāng)主集群出現(xiàn)故障的時候,備用集群啟用。
這種方案其實不太靠譜,因為備用集群正常情況下是不啟用的,所以其代碼,配置,數(shù)據(jù)都有可能是沒有經(jīng)過驗證的,萬一真的發(fā)生問題時,慌忙啟動的備用集群大多數(shù)情況也是不可用的。
多活
多活就是所有的集群都是正常提供服務(wù)的。正常情況下會按照流量劃分,將流量歸屬到不同的集群,當(dāng)某集群出現(xiàn)問題時,將流量切換到其他集群正常提供服務(wù)。
多活是高可用架構(gòu)設(shè)計的保障,根據(jù)多活等級的要求不同,多活還有同城雙活,異地雙活,兩地三中心,三地五中心等。對多活的要求越高,投入的資源也就會越高。這里就不再詳細(xì)講述這些名字背后的技術(shù)細(xì)節(jié)了。
多云多活的技術(shù)細(xì)節(jié)
多云多活指的是公司選擇兩家云服務(wù)商,將服務(wù)部署兩個云上,正常情況兩個云同時對外提供服務(wù),當(dāng)其中一個云出現(xiàn)問題時,將流量全都切換到另外一個云。

這個圖基本是大多數(shù)公司部署多云多活的技術(shù)方案,下面聊聊這個方案的相關(guān)技術(shù)細(xì)節(jié)和缺點。
這個架構(gòu)的大概流程:
客戶端通過接入層訪問系統(tǒng)相關(guān)服務(wù) 接入層根據(jù)流量分發(fā)規(guī)則,將流量向下分發(fā)到業(yè)務(wù)層 業(yè)務(wù)層經(jīng)過相關(guān)的業(yè)務(wù)邏輯處理,將相關(guān)數(shù)據(jù)寫入到相關(guān)的存儲中
流量分發(fā)/切換
分布在不同的兩個云的集群的系統(tǒng)承載能力是需要經(jīng)過評估的,流量接入層按照系統(tǒng)承載能力的差異,將流量按照不同的比例進(jìn)行分發(fā)。不過一般情況下,兩個云的系統(tǒng)會盡量保證系統(tǒng)的承載能力是一致的,所以流量是平分到兩個集群中。
當(dāng)某個云發(fā)生故障的時候,在流量接入層會將流量全部切換到另外一個云上,保證另外一個云的故障不會用戶造成影響。由此可見流量接入的層的重要性,不過這一層組件比較成熟,在我經(jīng)歷的項目中,這一層確實沒有發(fā)生過故障。
業(yè)務(wù)層雙活
業(yè)務(wù)層對于雙云雙活來說,其實比較簡單的,就是將同樣的代碼分別部署到兩個云即可。
但是要注意的是,這一層是有 IDC 之分的,要保證的是云1 的服務(wù)不能訪問到云2 去,對于開發(fā)人員來說也不用太擔(dān)心,只要配置不出錯,一般業(yè)務(wù)框架會保證這個事情。
再扯一點其他的,業(yè)務(wù)層正常情況下會根據(jù)業(yè)務(wù)需求快速迭代,這就給業(yè)務(wù)系統(tǒng)帶來了不穩(wěn)定性。如果 CI/CD 做的好的話,能夠讓業(yè)務(wù)做到快速回滾,但是這也會給核心業(yè)務(wù)造成一定的影響。為了解決這個問題,需要將核心業(yè)務(wù)進(jìn)行隔離,讓新上線的業(yè)務(wù)在非核心集群進(jìn)行驗證,等待穩(wěn)定后再部署到核心集群。

存儲層

先提出一個問題:存儲層這樣設(shè)計是否有問題?
這個設(shè)計還是蠻普遍的,比如 《斗魚基于etcd和ZooKeeper的注冊中心實踐案例》這篇文章中,對于存儲基本也是這樣設(shè)計的。
redis、mysql 還是選擇經(jīng)典的一主多從的設(shè)計方式。
選擇一個 “云” 將 mysql/redis 的主節(jié)點和部分從節(jié)點部署到這個云上 將 mysql/redis 其他的從節(jié)點部署到另外一個云上 redis/mysql 之間利用主從同步機(jī)制進(jìn)行數(shù)據(jù)同步 云1 和 云2 之間由一條專線連接
優(yōu)點
架構(gòu)簡單,可以利用 redis、mysql 自身的機(jī)制進(jìn)行數(shù)據(jù)同步,讓數(shù)據(jù)的訪問在各自的云進(jìn)行。
缺點
其實缺點一眼就看出來了,這整個“雙云雙活”的設(shè)計的缺點太依賴于主節(jié)點所在的云的穩(wěn)定性和專線的穩(wěn)定性。
在我經(jīng)歷的項目,云的穩(wěn)定性還是可以的,最容易出現(xiàn)問題的其實這條專線,比如:專線被打滿。當(dāng)專線出現(xiàn)問題時,研發(fā)只能傻樂,等待運維恢復(fù)專線,如何保證這個專線的穩(wěn)定性成為這個架構(gòu)最重要的事情。
當(dāng)然另外一個問題也是很難解決:主節(jié)點所在的云或者專線發(fā)生故障的時候,整個項目其實也就癱瘓了大半。
因為當(dāng)主節(jié)點所在的云出現(xiàn)故障時,在流量接入層可以將流量切換到另外一個集群,但是我們的主業(yè)務(wù)肯定不是”只讀“的,肯定還有寫業(yè)務(wù)存在, 于是出現(xiàn)故障的時候,只能看到一堆堆的寫失敗報警,有些業(yè)務(wù)接口肯定也在報錯,只能等待故障恢復(fù)后,人工補(bǔ)償這些寫失敗的數(shù)據(jù)。
所以為了解決這個系統(tǒng)設(shè)計的缺陷,就是要將 redis/mysql 做成多主多從,主與主集群之間做數(shù)據(jù)同步。這個方案說起來容易,但是實踐起來就太困難了。
這里只使用 mysql/redis 作為示例來解釋雙云雙活,其實我們的系統(tǒng)還有另外一些分布式一致性系統(tǒng)如:ectd,讀者可以考慮一下如何部署到雙云上面。
結(jié)論
其實很多的公司的多活最終都因為各種原因淪為了“偽多活”。 非云,非BAT級別的廠,一般建義先做到核心數(shù)據(jù)(交易,用戶)多中心備份,畢竟不是每次火災(zāi)水災(zāi)都能趕上,當(dāng)某云出現(xiàn)問題時可以快速恢復(fù),這才是重中之重。
上面提高的“雙云雙活”方案的瓶頸就在于存儲層,讓整個集群處于“偽多活”的狀態(tài)。這個方案確實能解決一些問題,但是高可用并沒有想象中的那么出色,更多時候這樣項目一般都淪落成某些人晉升的 KPI。
寫文章不易請大家?guī)兔c擊 在看,點贊,分享。
