mongodb在雙活(主備)機房的部署方案和切換方案設計
1. 概述
現在很多高可用系統為了應對極端情況,比如主機宕機、網路故障以及機房宕機等災難的發生,通常會部署主備架構(雙機房),或者雙活架構(雙機房),甚至多活架構(三個機房或者以上),mongodb天然就適合部署雙機房或者多機房,但是在發生機房宕機災難時,也會遇到無法選舉主節點的問題,本文重點討論在主備或者雙活架構下的mongodb的部署方案和切換方案,下文中的討論以主備架構為例(雙活同理)。
2. 主備架構網路部署圖
在主備架構部署方案中,用戶請求都是路由到主機房,備用機房無用戶請求,為了簡化示意,這裡先把cdn、dns、waf等部分略去,重點突出應用和mongo集群內部節點的部署結構,如下圖:
從上圖可以看到,負載均衡和應用服務部分都是主備架構,mongodb集群是一體的(兩邊都會處理請求),沒有主備之分,只是部署在兩個機房而已。
當然,這種方式下,mongodb集群的資源利用率會高一些,不存在上層備用機房的應用服務的資源閑置浪費的問題。
3. mongodb的主備架構痛點
在主備架構環境中,mongodb的高可用部署方案,推薦複製組內的節點數是奇數(比如3個節點,1主2從),此時存在一個機房部署2個節點,一個機房部署1個節點,當部署2個節點的機房宕機時,由於另外一個機房只有1個節點,而mongodb的選舉協議是raft一致性協議,此時是無法選舉出主節點的(要求存活節點數大於原節點數的1/2),導致mongodb服務的不可用,示意圖如下:
4. mongodb主備部署方案
針對章節3中遇到的問題,我們調整了部署方案,即在備用機房準備一個備用節點,平時是不啟動的,僅在主機房災難發生時,才啟動該備用節點,示意圖如下:
5. mongodb的主備切換方案
部署方案已經有了,下面談一下主備切換方案,當主機房發生災難時,我們要解決兩個問題:
1. 怎麼啟動先前的備用節點。
2. 怎麼讓剛剛啟動的備用節點加入到複製組中,否則是無法參與主節點選舉的。
啟動備用節點
在備用節點上準備好啟動腳本,然後使用運維軟體(例如saltstack)發送啟動命令,即可啟動備用節點。
備用節點加入複製組
我們知道如果要把一個新的節點加入複製組,是需要在主節點執行rs.add命令的,但是在災難發生時,由於還沒有主節點,是無法使用這個辦法的,因此需要換一個思路,即讓備用節點「替換」原主機房的從節點,這裡的「替換」是指讓複製組的其他成員認為該備用節點,就是原來的從節點,技術方案如下:
1. 首先複製組內的成員,在加入複製組時,使用域名替換ip的方式,例如:rs.add(“shardA1.mongodb.net:27017”),同時修改mongodb集群所有伺服器的/etc/hosts文件,配置shardA1.mongodb.net和IP的映射關係。
2. 在災難發生時,先把mongodb集群內所有伺服器的/etc/hosts中shardA1.mongodb.net對應的IP修改為備用節點的IP,再啟動備用節點,此時複製組內的其他節點能快速連上新的節點。
解釋一下,為什麼把域名和IP的映射關係配置到hosts文件而不是配置到dns伺服器,主要是考慮到修改hosts文件生效更快,從而快速選舉出主節點。
小結
1. 該方案比較大的亮點是通過修改/etc/hosts文件的方式,讓新的節點可以加入集群,從而快速完成主節點選舉。
2. 該方案是一個比較通用的方案,適合很多分散式的系統使用,比如zookeeper等。
當然,在實施時,需要考慮主備雙向切換,主備切換後監控原主機房的原從節點是否被啟動等異常情景。
以上方案有任何不妥之處,歡迎斧正。