1. 副本集核心概念与高可用目标

MongoDB 副本集(Replica Set)是一组维护相同数据集的 mongod 进程集合,它通过冗余存储与自动故障转移,把单机数据库升级为具备持续服务能力的高可用集群。理解副本集,关键不是记住“一主多从”这个简化说法,而是弄清三件事:节点承担什么角色、主节点如何产生、主节点失效后系统如何恢复服务。这三件事共同决定了副本集能否真正满足业务对可用性的要求。

节点角色:Primary、Secondary 与 Arbiter

副本集中的每个成员都有一个角色,角色决定了它是否接受写入、是否保存数据、是否参与投票。

  • Primary(主节点):副本集中唯一接受写操作的成员。所有写入先落到 Primary,再由 Primary 通过 oplog 复制给其他成员。读操作默认也走 Primary,除非客户端配置了读偏好。
  • Secondary(从节点):持续从 Primary 拉取 oplog 并重放,从而保持与 Primary 的数据一致。Secondary 可以承担读请求(需配置读偏好),也可以在主节点失效时被选举为新的 Primary。
  • Arbiter(仲裁节点):只参与选举投票,不保存数据、不接受读写。它的价值在于以较低成本让副本集成员数达到奇数,从而在选举中形成多数派。Arbiter 不持有数据,因此不能成为 Primary。

一个典型的三成员副本集可以是“1 Primary + 2 Secondary”,也可以是“1 Primary + 1 Secondary + 1 Arbiter”。前者具备两份数据冗余,后者只有一份数据冗余但成本更低。选择哪种结构,取决于业务对数据安全与成本的双重要求。

选举机制:多数派如何决定新主

副本集的高可用核心是选举。当 Primary 不可达时,剩余的 Secondary 会发起选举,选出新的 Primary。选举能否成功,取决于“多数派”原则:一个候选节点必须获得副本集总投票成员中超过半数的票,才能成为 Primary。

假设副本集有 3 个投票成员,多数派为 2。若 Primary 宕机,剩下 2 个成员只要都参与投票,就能选出新主;若只剩 1 个成员可达,则无法达到多数派,副本集进入只读状态,无法接受写入。这就是为什么副本集成员数通常配置为奇数:3、5、7 成员能更高效地形成多数派,避免平票。

选举还受优先级(priority)影响。优先级高的节点在条件相同时更容易被选为 Primary。例如,可以把配置更好、网络更稳定的节点优先级设为 2,其他节点保持默认 1,从而引导主节点落在预期机器上。此外,节点还必须满足“数据足够新”的条件:其 oplog 落后程度不能超过配置的 catchUpTimeoutMillis 等约束,否则不会被选为 Primary,以避免数据回滚风险。

三成员副本集:角色、复制与选举 Primary 接受读写 priority: 2 oplog 写入源 Secondary 复制 oplog priority: 1 可被选举为新主 Secondary 复制 oplog priority: 1 可被选举为新主 oplog 复制 oplog 复制 选举投票 选举投票 多数派原则:3 个投票成员 → 多数派 = 2 票 Primary 失效后,剩余 2 个成员可选出新主;若仅剩 1 个可达,则无法写入

自动故障转移:从失效到恢复服务

自动故障转移是副本集区别于主从复制的重要能力。其过程可以概括为:检测失效、发起选举、选出新主、客户端重连。MongoDB 驱动通过心跳(默认每 2 秒一次)监测各成员状态。当 Primary 在 electionTimeoutMillis(默认 10 秒)内未响应,Secondary 会认为主节点不可用,进而发起选举。

选举成功后,新 Primary 开始接受写入,其他 Secondary 转而从新 Primary 复制。客户端驱动会自动发现新的主节点并重连,应用层通常无需修改代码。但需要注意:故障转移期间存在一个短暂窗口,写入会失败或阻塞,这个窗口的长度直接影响 RTO。

RPO 与 RTO:高可用的两个量化目标

高可用不能只停留在“能自动切换”的定性描述,必须用指标衡量。工程上最常用的两个指标是 RPO 和 RTO。

指标 含义 副本集语境下的影响因素
RPO 恢复点目标,即故障发生时允许丢失多少数据 写关注(writeConcern)级别、journal 配置、复制延迟
RTO 恢复时间目标,即故障后多久恢复服务 选举超时、心跳间隔、节点数量、网络状况、驱动重连策略

举例来说,若业务要求 RPO=0,则写入必须使用 { w: "majority", j: true },确保数据被多数派持久化后才返回成功。若业务要求 RTO 小于 30 秒,则需要合理设置 electionTimeoutMillis,并保证副本集成员网络低延迟、节点数量不过多。RPO 与 RTO 往往存在权衡:更严格的 RPO 意味着每次写入等待更多确认,可能增加写延迟;更短的 RTO 则要求更激进的失效检测,可能带来误判风险。

工程判断示例:某订单系统要求 RPO=0、RTO≤20 秒。可采用 3 成员副本集(1 Primary + 2 Secondary),写关注设为 majority,读关注设为 majority,electionTimeoutMillis 保持默认 10 秒。这样在单节点故障时,多数派仍可选出新主,且已确认写入不会丢失。若使用 Arbiter 替代一个 Secondary,则数据冗余降为一份,RPO 风险上升,不适合该场景。

理解副本集的关键视角

学习副本集时,建议始终围绕三个问题展开:数据写到哪里、谁来决定新主、故障期间业务会看到什么。数据写到 Primary 并通过 oplog 复制到 Secondary;新主由多数派选举产生,优先级和数据新鲜度影响结果;故障期间业务可能经历短暂写入失败,随后由驱动自动重连恢复。把这三个问题串起来,就能把节点角色、选举机制、故障转移和 RPO/RTO 统一到同一个高可用工程框架中,而不是把它们当作孤立知识点记忆。