結論,可以直接拖到最后,如果看不明白,免備案主機,可以從頭看起。
最近,公有云又出了些大故障,各大群和朋友圈又開始沸沸揚揚,但是整體看下來,聲音無非兩種:
單站點不靠譜,要有容災,出現這種情況就得馬上切,所以回去趕緊建設容災站點; 雞蛋不能放在一個籃子里,單云不靠譜,要多云。所以,多云就要選我們家的xx云,或者我們提供xx多云服務。
我在我的一個討論群里就提出來,第一種聲音是有意識的建設,有這個意識很好,但是把這個事情想得太簡單了。第二種聲音,基本就是不動腦子的瞎BB,原因我下面講。
轉回正題來,既然上篇提到主備模式不靠譜,那到底怎么選?而且整天見各類技術文章,不是雙活,就是多活,不是同城,就是異地,現在又出來個多云,好復雜。
下面我就談談我的理解:
首先,這么多名詞是什么含義,要搞清楚,然后再看適不適合。
先講相對簡單的雙活(簡不簡單,看后面就明白了),其實就是兩個站點,同時承載業務流量,可以根據用戶ID、地域或者其他業務屬性也決定怎么分擔流量,當一個站點故障時,可以快速(分鐘級)切換到另一個站點,理想情況下,對業務基本是無損或者非常小的。
這里就跟前面講的主備不同了,主備的另一個站點完全是不承載任何流量的。
這里再往深里看一眼,同時承載流量,也要看承載到那一層,也就是流量在統一站點內閉環,所有調用都是本機房內完成,還是只有應用層這樣的無狀態組件雙活,但是數據訪問、異步消息這些有狀態的部件還是回到主站點調用,這兩種模式又是不一樣的。
其實第二種,就比前面講的主備模式要好一些,因為這樣至少可以保證應用層隨時可用,不過真出故障的時候,還是少不了數據層的切換,這個其實是非常耗時的。跟主備模式一樣,基本無法演練,因為代價太高,數據會有損。(如果數據層沒有這么復雜,只有幾個數據庫,那是沒問題問題的,但是分布式的場景下,上百個,幾百個實例切換,這個代價和成本還是很大的。)
所以,再往下推導,如果想要做到有效果的雙活,就必須保證每個站點,都是獨立運行,所有的調用都是本機房調用且閉環,底層做好數據同步即可。
只有做到這個程度,當一個站點發生故障不可用時,就可以從接入層把故障站點的流量切換到另一個站點,雙活的效果也就有了。
不過,做到這個程度,就不是說我們想要做就能做到的,如果您做個類似的架構設計,你會知道這里有三個關鍵的技術點:
第一個,本機房調用
也就是一個分布式請求不能跨機房調來調去,這個是不行的,必須要保證本機房調用閉環。所以從分布式服務的路由策略上,以及服務化框架上,必須得支持這也中調用模式,同理,數據訪問層,以及消息組件也要支持這種特性。
第二個,數據分片和一致性
為什么要做這個事情?我們知道一個系統中數據準確性、完整性和一致性是非常關鍵的,放到雙活這個場景下,歐洲服務器租用,最關鍵的就是數據一致性,我們不能允許有同一個記錄兩邊同時在變更,還要雙向同步,比如用戶交易和支付類的數據,同時變更的情況下,我們無法確認哪邊是準確的。
前面提到,兩個站點是同時承載不同的流量的,這就要根據一些業務屬性來分配,比如用戶ID、所屬地域等等策略,這里為的就是能夠在數據層面也要做好隔離,一個站點內只提供固定部分的用戶訪問。
這樣就保證了單站點內同一分片的數據,不會在另外一個站點被變更,后續的同步也可以做到單向。
所以,這里的關鍵,就是數據要做分片,就要用到分布式的數據中間件,要做數據訪問的路由設計,數據要同機房讀寫,還要做數據拆分這樣的工作,技術門檻和工作量也不低。
這兩點如果能夠做到,其實就是我們經常說的“單元化”架構達成了,理論上,我們可以選擇任何一個機房和地域,把系統搭建起來,就可以提供業務訪問了。
但現實是更為復雜的,因為用戶業務系統產生的數據,有可能會被其它系統用到,比如商品庫存這樣的系統,這就要涉及異步消息和數據的同步問題,而數據同步不僅僅是一個技術問題,而是個物理問題,我們接下來講。
第三個,數據同步。
其實單從同步角度而言,目前很多的同步工具和開源產品已經比較完善,所以這里最大的問題,其實不在技術層面,而是在物理層面。
準確點,就是物理距離上的時延問題,這個無論是雙活、多活,還是同城、異地,都繞不開的痛苦問題。