MongoDB主备副本集方案:两台服务器使用非对称部署的方式实现高可用与容灾备份

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云原生多模数据库 Lindorm,多引擎 多规格 0-4节点
云数据库 Tair(兼容Redis),内存型 2GB
简介: 在资源受限的情况下,为了实现MongoDB的高可用性,本文探讨了两种在两台服务器上部署MongoDB的方案。方案一是通过主备身份轮换,即一台服务器作为主节点,另一台同时部署备节点和仲裁节点;方案二是利用`priority`设置实现自动主备切换。两者相比,方案二自动化程度更高,适合追求快速故障恢复的场景,而方案一则提供了更多的手动控制选项。文章最后对比了这两种方案与标准三节点副本集的优缺点,指出三节点方案在高可用性和数据一致性方面表现更佳。

昨天(2024/11/18)碰到这么个问题,因为要控制成本,公司只愿意出两台服务器(很小的盒子)部署业务,采用传统的主备模式。这其中就包括Mongodb数据库,最稳固的方法当然是采用官方推荐的最低3台。但没办法,只能是模拟部署了。

选举机制踩坑-必须获得超过半数票

一开始冒出来的想法是各部署两个mongodb节点(2+2),这样挂掉还有一半,但是实测不会进行选举,集群会卡住不可用!

后来我想,是不是因为偶数的原因,试了下(3+3),结果还是不可用。因为我问gpt说是获得的票数是 votes > ceil(total/2),被个ceil给坑了。因为按照这个设定,我以为是>=,不然3个节点挂一个就应该不可用。

实际上只要超过半数就可以,奇数的不会出现对等,所以更好控制!
另外三节点,挂掉一个后,rs.status() 会出现错误 : Error: Invalid UTF-8 string in BSON document

方案一:主备身份轮换

部署拓扑结构

在方案一中,我们使用两台服务器,部署一个主实例(Primary)和一个备用实例(Secondary),并额外配置一个投票节点(Arbiter)来保证选举的有效性。

  • 服务器A(主服务器):部署一个MongoDB实例(Primary)
  • 服务器B(备用服务器):部署一个MongoDB实例(Secondary)和一个Arbiter实例
graph LR
    A[服务器A - MongoDB Primary] --> B[服务器B - MongoDB Secondary]
    B --> C[服务器B - Arbiter]
AI 代码解读

实现步骤

  1. 初始配置

    • 服务器A上的MongoDB实例被设置为Primary节点。
    • 服务器B上的MongoDB实例被配置为Secondary,并在服务器B上额外部署一个Arbiter实例,用于选举。
    • 副本集初始化完成后,服务器A作为Primary处理所有写操作,服务器B作为Secondary提供读操作(如果配置为允许读操作)。
  2. 故障切换与维护流程

    • 故障切换:当Primary节点(服务器A)发生故障时,备用服务器B发起选举,获得自身和Arbiter的投票,从而成为新的Primary。
    • 维护切换:在需要手动切换主备角色时,可以先停止服务器A,将服务器B设置为Primary并确保其稳定运行,随后启动服务器A作为新的Secondary节点,并重新配置副本集。

数据一致性影响

  • 在此方案中,主备切换可能存在短暂的写入中断,特别是在Primary节点发生故障时,需要等待选举完成。
  • 若在Secondary节点成为新的Primary期间,未及时同步的数据可能会导致数据一致性风险,具体取决于复制滞后的程度和写入操作量。

客户端连接

客户端连接时需要使用副本集连接字符串,确保在Primary节点切换时能够自动连接新的Primary:

graph LR
    Client[客户端] --> A[服务器A - MongoDB Primary]
    Client --> B[服务器B - MongoDB Secondary]
AI 代码解读

方案二:基于priority的自动主备切换

部署拓扑结构

与方案一类似,方案二也依赖于两台服务器,但通过设置不同的priority来实现自动化的主备角色管理。

  • 服务器A(主服务器):Primary节点,配置较高的priority
  • 服务器B(备用服务器):Secondary节点,配置较低的priority,并包含一个Arbiter节点
graph LR
    A[服务器A - MongoDB Primary, Priority高] --> B[服务器B - MongoDB Secondary, Priority低]
    B --> C[服务器B - Arbiter]
AI 代码解读

实现步骤

  1. 配置优先级

    • 服务器A的priority值设置较高,确保在正常运行时始终担任Primary节点。
    • 服务器B的priority值设置较低,通常作为Secondary节点,但在Primary发生故障时会自动升级为Primary。
  2. 故障恢复与抢占

    • 当服务器A发生故障,备用服务器B会自动成为Primary节点,继续处理写入请求。
    • 服务器A恢复并重新加入副本集后,由于其priority值较高,会自动抢占Primary角色,恢复为主服务器。

数据一致性影响

  • 通过自动优先级切换,方案二能够更快响应主备角色的变化,减少切换过程中的写入中断。
  • 若发生网络分区或短暂故障,可能会导致短暂的"脑裂"风险。通过配置Arbiter节点,该风险可以得到一定程度的缓解。
  • 自动抢占可能引发短暂的切换过程,尤其是在较高负载下时,需要注意数据的一致性和写入冲突的处理。

客户端连接

客户端连接时也应使用副本集连接字符串,确保自动连接当前的Primary节点:

graph LR
    Client[客户端] --> A[服务器A - MongoDB Primary, Priority高]
    Client --> B[服务器B - MongoDB Secondary, Priority低]
AI 代码解读

方案对比

比较项 方案一:手动主备切换 方案二:基于priority的自动主备切换
实现复杂度 较高,需要手动干预和配置 较低,配置完成后自动处理
主备切换响应速度 需要一定的手动干预时间 自动响应,通常较快
灵活性 较高,可以控制主备角色转换的时机 灵活性相对较低,但自动化程度高
维护成本 需要手动操作和关注角色切换 自动维护成本较低
适用场景 需要较强的角色控制时,例如关键业务维护期间 适用于高可用和快速故障切换的场景

与三台设备组成的副本集对比

在标准的三节点副本集架构中,通常由一个Primary节点和两个Secondary节点组成,无需额外的Arbiter来参与投票,具备更好的高可用性和数据一致性保障。

三节点副本集的优势

  1. 更高的数据一致性

    • 数据在三节点中分布复制,出现节点故障时,仍能确保数据存在于至少两个节点上,从而减少数据丢失的风险。
    • 不同于两节点加Arbiter的方案,三节点架构能够更好地应对网络分区问题,降低“脑裂”风险。
  2. 自动化程度更高

    • 无需额外配置投票节点,节点之间的选举更加自然。
    • 主备切换流程中断更短,因三个节点始终存在一个备用Secondary作为下一任Primary候选。
  3. 扩展性更好

    • 在需要进一步扩展时,三节点副本集更容易增加节点,提升整体性能和可靠性。

两节点方案的局限性

  • 高可用性略低:由于仅有一个Secondary节点,任意节点故障都会显著影响集群的可用性。
  • 选举机制更复杂:需要通过Arbiter来确保选举票数多数,不如三节点架构直接稳定。
  • 维护复杂度更高:在进行角色切换时,需要手动操作或依赖于不同的priority配置,增加维护成本。

结论

  • 方案一适合需要更严格控制主备切换时机的场景,能够手动调整和维护,但维护成本较高。
  • 方案二通过priority实现自动切换,适合追求高可用性和快速故障响应的场景,但需要额外注意抢占过程中可能出现的临时一致性问题。
  • 相比于标准的三节点副本集,两节点方案具备一定的局限性和风险,适用于资源有限但需要基本高可用性的环境。三节点方案更为稳健,推荐在资源充足的情况下使用。

通过合理选择和配置,可以实现符合业务需求的MongoDB副本集方案,提高数据库系统的容灾能力和高可用性。

附录 - 启动脚本

说明: mongodb7.0 + windows 环境测试

副本集创建

简单的把数据放在三个目录去

.\mongod.exe --port 27017 --dbpath G:/mongo/node1/data --logpath G:/mongo/node1/log/mongo.log --replSet rs 

.\mongod.exe  --port 27018 --dbpath G:/mongo/node2/data --logpath G:/mongo/node2/log/mongo.log --replSet rs

.\mongod.exe  --port 27019 --dbpath G:/mongo/node3/data --logpath G:/mongo/node3/log/mongo.log --replSet rs
AI 代码解读

副本集初始化

rs.initiate({
  _id: "rs",
  members: [
    { _id: 0, host: "localhost:27017" },
    { _id: 1, host: "localhost:27019" }
  ]
})
AI 代码解读

一定概率不让直接加投票节点,需要配置默认writeConcern

db.adminCommand({
  "setDefaultRWConcern" : 1,
  "defaultWriteConcern" : {
    "w" : 1
  }
})
AI 代码解读

添加投票节点

rs.addArb("localhost:27018")
AI 代码解读
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
打赏
0
5
5
1
58
分享
相关文章
DeepSeek服务器繁忙解决方法:使用阿里云一键部署DeepSeek个人网站!
通过阿里云一键部署DeepSeek个人网站,解决服务器繁忙问题。学生用户可领取300元代金券实现0成本部署,普通用户则可用99元/年的服务器。教程涵盖从选择套餐、设置密码到获取百炼API-KEY的全流程,助您快速搭建专属大模型主页,体验DeepSeek、Qwen-max、Llama等多款模型,无需代码,最快5分钟完成部署。支持绑定个人域名,共享亲友使用,日均成本仅约1元。
130 10
网络通讯技术:HTTP POST协议用于发送本地压缩数据到服务器的方案。
总的来说,无论你是一名网络开发者,还是普通的IT工作人员,理解并掌握POST方法的运用是非常有价值的。它就像一艘快速,稳定,安全的大船,始终为我们在网络海洋中的冒险提供了可靠的支持。
59 22
Vue项目部署:如何打包并上传至服务器进行部署?
以上就是Vue项目打包及部署的方法,希望对你有所帮助。描述中可能会有一些小疏漏,但基本流程应该没有问题。记住要根据你的实际情况调整对应的目录路径和服务器IP地址等信息。此外,实际操作时可能会遇到各种问题,解决问题的能力是每一位开发者必备的技能。祝你部署顺利!
139 17
Docker——阿里云服务器使用Docker部署python项目全程小记
本文记录了我在阿里云服务器上使用Docker部署python项目(flask为例)的全过程,在这里记录和分享一下,希望可以给大家提供一些参考。
142 0
【已解决】Matomo本地SMTP配置可以发邮件,但部署到阿里云ECS就发不了邮件
在阿里云ECS上使用Matomo和PHPMailer发送邮件时遇到问题,邮件无法发出且接口调用Pending。经过排查,发现是ECS安全组未开放25/465端口,导致SMTP请求无法正常通信。解决方法为在安全组中配置并开放25/465端口,从而恢复邮件发送功能。
Linux服务器部署docker windows
在当今软件开发中,Docker成为流行的虚拟化技术,支持在Linux服务器上运行Windows容器。流程包括:1) 安装Docker;2) 配置支持Windows容器;3) 获取Windows镜像;4) 运行Windows容器;5) 验证容器状态。通过这些步骤,你可以在Linux环境中顺利部署和管理Windows应用,提高开发和运维效率。
154 1
使用域名访问部署在ECS上的网站
本文为您介绍如何为网站配置域名并为域名配置HTTPS证书。
数据库数据恢复——MongoDB数据库服务无法启动的数据恢复案例
MongoDB数据库数据恢复环境: 一台Windows Server操作系统虚拟机上部署MongoDB数据库。 MongoDB数据库故障: 管理员在未关闭MongoDB服务的情况下拷贝数据库文件。将MongoDB数据库文件拷贝到其他分区后,对MongoDB数据库所在原分区进行了格式化操作。格式化完成后将数据库文件拷回原分区,并重新启动MongoDB服务。发现服务无法启动并报错。
|
28天前
|
微服务——MongoDB常用命令1——数据库操作
本节介绍了 MongoDB 中数据库的选择、创建与删除操作。使用 `use 数据库名称` 可选择或创建数据库,若数据库不存在则自动创建。通过 `show dbs` 或 `show databases` 查看所有可访问的数据库,用 `db` 命令查看当前数据库。注意,集合仅在插入数据后才会真正创建。数据库命名需遵循 UTF-8 格式,避免特殊字符,长度不超过 64 字节,且部分名称如 `admin`、`local` 和 `config` 为系统保留。删除数据库可通过 `db.dropDatabase()` 实现,主要用于移除已持久化的数据库。
66 0

相关产品

  • 云数据库 MongoDB 版