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等。

當然,在實施時,需要考慮主備雙向切換,主備切換後監控原主機房的原從節點是否被啟動等異常情景。

以上方案有任何不妥之處,歡迎斧正。