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等。
当然,在实施时,需要考虑主备双向切换,主备切换后监控原主机房的原从节点是否被启动等异常情景。
以上方案有任何不妥之处,欢迎斧正。