4. MongoDB集群架构规划

当单机 MongoDB 无法同时满足数据冗余、读写扩展和故障自动恢复时,就需要进入集群架构规划阶段。MongoDB 的集群能力由两个正交维度组成:副本集解决高可用与数据冗余,分片集群解决水平扩展与数据分布。理解这两者的组合关系,是设计企业级部署拓扑的前提。

副本集:高可用的最小单元

副本集是一组维护相同数据集的 mongod 实例。其中只有一个节点是 Primary,承担全部写操作与默认读操作;其余节点为 Secondary,通过持续复制 oplog 保持数据同步。当 Primary 不可达时,副本集通过选举机制在数秒内选出新的 Primary,实现自动故障转移。

节点角色除 Primary/Secondary 外,还有两类特殊成员:Arbiter(仲裁节点)只参与投票、不持有数据,用于以低成本凑齐奇数票;Priority 0 节点持有数据但优先级为 0,永不主动成为 Primary,常用于多数据中心中的灾备节点或只读分析节点。规划时需注意:副本集成员数建议为奇数(3、5、7),因为选举需要多数票(N/2+1)。3 节点可容忍 1 节点故障,5 节点可容忍 2 节点故障。

一个典型的三节点副本集配置如下,其中 _id 为副本集名称,priority 控制选举倾向,hidden 用于隐藏只读节点:

rs.initiate({
  _id: "rs_order",
  members: [
    { _id: 0, host: "mongo-a:27017", priority: 2 },
    { _id: 1, host: "mongo-b:27017", priority: 1 },
    { _id: 2, host: "mongo-c:27017", priority: 1 }
  ]
})

写入时通过 Write Concern 控制确认级别:w:1 只等 Primary 确认,w:"majority" 等待多数节点落盘,后者在故障切换时更安全但延迟更高。读取时通过 Read Preference 控制路由:primary 保证强一致,secondaryPreferred 可分担读压力但可能读到略旧数据。这两组参数是副本集规划中必须与业务一致性要求对齐的核心决策。

分片集群:水平扩展的拓扑

当单副本集的数据量或写入吞吐超过单机上限时,需要引入分片集群。分片集群由三个组件构成:mongos 路由节点接收客户端请求并转发到正确分片;config server 副本集存储集群元数据(分片键范围、块分布);shard 分片各自是一个副本集,实际存储数据子集。

分片的核心是分片键(Shard Key)的选择。分片键决定数据如何分布到各分片,常见策略有范围分片(range)和哈希分片(hashed)。范围分片适合范围查询但易产生热点;哈希分片分布均匀但范围查询需广播到所有分片。分片键一旦设定不可更改,因此必须在建库前根据查询模式确定。

下面是一个分片集群的初始化示例,先启用分片,再对集合按哈希分片键分片:

sh.enableSharding("order_db")
sh.shardCollection("order_db.orders", { orderId: "hashed" })
sh.status()

执行 sh.status() 后可观察各分片持有的块数量是否均衡。若某分片块数明显偏多,说明分片键分布不均,需要重新评估分片键或触发均衡器。

高可用部署拓扑设计

企业部署通常跨机房或跨可用区。以三机房为例,推荐将副本集成员按 2:1:0 或 2:2:1 分布,确保任一机房故障时仍有多数票存活。若采用两地三中心,可将 Primary 与一个 Secondary 放在主中心,另一个 Secondary 放在同城灾备中心,Arbiter 放在第三站点。需注意:Arbiter 不存数据,跨机房部署时网络延迟对其影响较小,但不应将多数投票成员集中在同一故障域。

分片集群中,mongos 是无状态节点,可部署多个并置于负载均衡之后;config server 必须部署为副本集(通常 3 节点),其可用性直接决定集群元数据可读性;每个 shard 自身也是副本集,需独立规划其成员分布。整体拓扑应保证:任一单点故障不导致集群不可写,任一机房故障不导致多数票丢失。

MongoDB 分片集群 + 副本集高可用拓扑 应用客户端 mongos 路由节点(无状态) config server 副本集 元数据 / 块分布 Shard 分片层(每个分片为一个副本集) Shard 1 副本集 Primary Secondary Secondary oplog 复制 · 自动选举 Shard 2 副本集 Primary Secondary Secondary oplog 复制 · 自动选举 Shard 3 副本集 Primary Secondary Secondary oplog 复制 · 自动选举 分片副本集 路由转发 元数据存储

规划要点与常见误区

第一,副本集成员数应为奇数。若因成本限制只能部署 2 个数据节点,应增加 1 个 Arbiter 而非再增加 1 个数据节点,否则无法形成多数票。第二,分片键选择不可逆,应在业务建模阶段就根据高频查询字段确定,避免上线后因热点问题被迫重建集合。第三,config server 不可与 mongos 混部,其稳定性直接影响整个集群的元数据可读性。第四,跨机房部署时,应确保多数投票成员位于同一低延迟网络内,否则选举超时会导致频繁切换。

规划检查清单:① 副本集成员数是否为奇数?② 多数投票成员是否分布在不同故障域?③ 分片键是否匹配高频查询模式?④ Write Concern 是否与业务一致性要求对齐?⑤ config server 是否独立部署为 3 节点副本集?⑥ mongos 是否部署多个并置于负载均衡之后?

综上,副本集与分片集群并非二选一,而是可以叠加使用:每个分片本身就是一个副本集,config server 也是副本集。企业级部署拓扑的设计目标,是在成本、延迟与可用性之间找到平衡点,确保任一单点或单机房故障都不会导致集群整体不可用。