图解 MongoDB 18|复制集拓扑:Primary、Secondary 和 Arbiter 的分工

存储引擎阶段回答了「数据怎么存、怎么不丢」,但留下一个致命问题:单机宕机了怎么办。一台 mongod 进程挂掉,不管是硬件故障、进程崩溃还是网络隔离,所有读写都会中断。这在生产环境是不可接受的。

MongoDB 解决单点故障的方式是复制集(Replica Set)------把数据复制到多个节点,一台挂了自动切换到另一台。这一阶段(18--23)就围绕复制集展开,从拓扑结构、复制原理、延迟、选举到读写关注,把 MongoDB 的高可用讲透。

先把机制边界说清楚

复制集是一组维护相同数据集的 mongod 实例。它的核心特征是:

  • 一个 Primary,多个 Secondary。Primary 是唯一接受写入的节点,Secondary 从 Primary 异步复制数据。
  • 自动 failover。Primary 宕机时,Secondary 们会自动选举出一个新 Primary,不需要人工介入。
  • 奇数节点。为了保证选举能形成多数派,复制集通常是奇数节点(3、5、7)。

复制集和简单的「主从复制」(比如 MySQL 的异步主从)有本质区别:主从复制是「数据同步」,主挂了要人工切;复制集是「带选举的高可用集群」,主挂了自动切。MongoDB 没有传统的「主从」概念,生产环境的最小形态就是 3 节点复制集。

三种节点角色

把三种节点画在一起,分工立刻清晰:Primary 管写,Secondary 备份数据和分担读,Arbiter 只为投票。

Primary(主节点) 。复制集里唯一接受写入的节点。所有写操作先进 Primary,Primary 把写操作记到 oplog(操作日志),Secondary 拉取 oplog 重放来实现复制。Primary 默认也接受读(readPreference: primary)。Primary 宕机或失联时,会触发选举,从 Secondary 里选出新 Primary。

Secondary(从节点)。Primary 的数据副本,通过异步拉取 oplog 保持数据同步。Secondary 的能力比单纯备份强得多:

  • 可被选为 Primary。当 Primary 故障,符合条件的 Secondary 会参与选举。
  • 可接受读 。通过 readPreference 配置,应用可以把读请求分发到 Secondary,分担 Primary 压力。
  • 可定制角色 。比如 priority: 0 的 Secondary 永远不会被选为 Primary(适合做纯备份或异地节点);hidden: true 的 Secondary 对应用不可见(适合做报表分析);delayed 的 Secondary 延迟同步(适合防误删,延迟节点保留几小时前的数据)。

Arbiter(仲裁节点) 。一个特殊节点,不存数据,只参与投票。它的存在是为了凑齐奇数节点------比如只有两台数据机器时,加一个 Arbiter 凑成 3 节点,保证选举能形成多数派。Arbiter 不能被选为 Primary(它没数据),资源开销极小。但它只是权宜之计,真正的生产复制集应该是 3 个数据节点,而不是 2 数据 + 1 Arbiter(因为 Arbiter 不提供数据冗余)。

为什么必须是奇数节点

复制集的选举依赖多数派(majority)------要超过半数节点同意才能选出 Primary。奇数节点能保证多数派明确:

  • 3 节点:多数派是 2。任何 1 个节点挂了,剩下 2 个仍能形成多数派,继续工作。
  • 5 节点:多数派是 3。可以容忍 2 个节点同时故障。

偶数节点会有「脑裂」风险:4 节点如果分裂成 2+2,两边都拿不到 3 票多数派,无法选举,整个集群不可用。奇数节点避免了这种对称分裂。所以复制集规模总是奇数,哪怕用 Arbiter 凑。

复制集怎么实现高可用

把高可用拆成两个能力:

数据冗余 。Primary 的数据被复制到多个 Secondary,任何一个节点故障,数据都不丢(前提是用了 w: "majority")。这是「不丢」的保证。

自动 failover。Primary 故障时,Secondary 检测到(心跳超时),发起选举,选出新 Primary,应用 driver 自动重连到新 Primary。整个过程通常在 10--30 秒完成,期间写不可用(因为只有一个 Primary),读如果配了 Secondary 读则不受影响。这是「不断」的保证。

这两个能力合起来,就是复制集相对单机的核心价值。下一篇会深入 oplog,讲清楚 Secondary 到底是怎么「复制」的。

部署形态的选择

最小生产复制集:3 节点(1 Primary + 2 Secondary)。容忍 1 个节点故障,数据有 2 份冗余。这是绝大多数业务的起点。

两数据节点 + 1 Arbiter。机器有限时用,能容忍 1 个数据节点故障。但数据只有 1 份冗余(Arbiter 不算),不如 3 数据节点安全。只适合「实在没有第三台机器」的场景。

5 节点。容忍 2 个节点同时故障,适合更高可用要求。通常跨机房部署(比如两地三中心,后面专门讲)。

跨可用区部署。把节点分散到不同可用区/机房,避免单机房故障导致整个复制集不可用。这是云上部署的标准做法。

取舍与边界

复制集的代价:

  • 写入有放大 。每个写要复制到 Secondary,Secondary 也要写一遍。w: "majority" 还要等多数节点确认,延迟更高。
  • 读 Secondary 可能不一致。Secondary 异步复制,有延迟,读到的数据可能比 Primary 旧(最终一致性)。
  • 选举期间写不可用。Primary 切换的 10--30 秒,写操作会失败或排队。对写敏感的业务要有重试机制。
  • 运维复杂度。3 个节点要分别监控、分别备份,比单机复杂。

版本演进上,MongoDB 持续优化了选举速度(更快的心跳和选举协议)、复制效率(streaming replication)和一致性保证。但「Primary 写 + Secondary 异步复制 + 多数派选举」这套骨架始终稳定。

判断框架

  • 生产环境最小形态是 3 数据节点,不要用单机跑生产。
  • 节点数必须是奇数,凑不齐用 Arbiter,但 Arbiter 不提供数据冗余。
  • Primary 唯一写,Secondary 可分担读(但要接受最终一致性)。
  • 高可用 = 数据冗余(多副本)+ 自动 failover(选举),缺一不可。
  • 跨可用区部署避免单机房故障,是云上标配。
  • 选举期间写不可用,写敏感业务要有重试。

下一篇讲 oplog,看清复制的真正载体。


关于十三Tech

All in AI Agent 方向的架构师,专注 AI 工程实践。

相信 AI 是程序员的最佳搭档,帮助每一位开发者驾驭 AI。

公众号搜索「十三Tech」

本文首发:rubyfun.cn/posts/%E5%9...

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
晨米酱3 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
大勇前进3 天前
原生 PHP 还是 Laravel?小项目到底要不要上框架
后端
yuzhi_liu3 天前
我用 LangGraph4j 实现 Multi-Agent Supervisor
后端
alsmile3 天前
Node-RED 之外,国产规则引擎的新方案:基于标准语法,Go 先行实现
后端·开源·go
大白803 天前
PHP 内存溢出排查思路:看懂报错日志,精准定位问题
后端
二月龙3 天前
PHP 接口返回统一响应封装,让前后端对接更省心
后端