2. MongoDB集群架构深度解析

MongoDB 的高可用与水平扩展能力,来自一套分工明确的集群组件体系。理解这套体系,是后续做自动化部署、监控、故障切换和容量治理的前提。本节把副本集、分片集群、配置服务器、路由节点和仲裁节点放在同一张架构图上讲清楚,并说明每个组件在自动化运维中意味着什么。

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

副本集(Replica Set)是一组维护同一份数据集的 mongod 实例,其中只有一个主节点(Primary)接受写操作,其余为从节点(Secondary)通过 oplog 持续复制主节点数据。当主节点不可达时,副本集通过选举产生新的主节点。副本集是 MongoDB 高可用的基础,也是分片集群中每个分片的基本组成形式。

一个典型的三节点副本集包含:1 个 Primary、1 个 Secondary、1 个 Arbiter(或第三个数据节点)。关键参数包括:

  • rs.initiate():初始化副本集配置,写入 local.system.replset。
  • priority:节点优先级,取值 0~1000,值越高越容易被选为 Primary;设为 0 的节点永不主动竞选。
  • votes:是否参与选举投票,仲裁节点 votes=1 但不持有数据。
  • writeConcern:写关注,如 {w:"majority", j:true},决定写操作需要被多少个节点确认。
  • readPreference:读偏好,如 primary、secondaryPreferred,决定读请求路由到哪类节点。

从自动化运维角度看,副本集的核心含义是:节点角色会动态变化。自动化脚本不能假设某个 IP 永远是 Primary,而应通过 rs.status() 或 db.hello() 动态获取当前角色,再决定备份、索引构建、监控采集等操作的目标节点。

二、分片集群:水平扩展的完整拓扑

当单副本集容量或写入吞吐达到瓶颈时,需要引入分片集群(Sharded Cluster)。分片集群由三类角色组成:

  • Shard(分片):每个分片是一个独立的副本集,存储部分数据。分片键(Shard Key)决定数据如何分布到各分片。
  • Config Server(配置服务器):存储集群元数据,包括分片键范围、chunk 分布、分片列表等。MongoDB 3.4 之后要求配置服务器本身也必须是副本集(CSRS)。
  • Mongos(路由节点):无状态的路由进程,接收客户端请求,根据配置服务器中的元数据将请求转发到对应分片,并聚合结果返回。

分片集群的数据流可以概括为:客户端 → mongos → 根据 config server 元数据定位 chunk → 目标 shard 副本集 → 返回结果。mongos 本身不持久化数据,可以水平扩展多个实例,客户端连接串中通常列出多个 mongos 地址。

三、配置服务器与路由节点的运维含义

配置服务器(Config Server)是分片集群的“大脑”。它保存的 config 数据库包含 shards、chunks、collections 等集合。一旦配置服务器不可用,mongos 无法刷新元数据,集群可能无法正常路由请求。因此配置服务器必须部署为至少三节点副本集,且不建议与分片数据节点混部。

路由节点(mongos)是“无状态入口”。这意味着:

  • 可以随时增加或减少 mongos 实例,不影响数据持久性。
  • mongos 故障不会导致数据丢失,但会导致该入口不可用,需要客户端或负载均衡层切换。
  • 自动化运维中,mongos 的监控重点是连接数、路由延迟、到 config server 和 shard 的网络连通性。

四、仲裁节点:低成本投票者

仲裁节点(Arbiter)是一个不持有数据、只参与选举投票的 mongod 实例。它的价值在于:用较低成本让副本集获得奇数投票成员,避免出现平票。例如两数据节点 + 一仲裁节点,可以在不增加存储成本的情况下满足多数派选举要求。

但仲裁节点也有明显限制:它不参与数据复制,不能提升读能力,也不能在数据节点全部故障时恢复数据。因此生产环境中,如果预算允许,优先使用三数据节点副本集,而不是依赖仲裁节点。

仲裁节点一旦丢失,副本集可能失去多数派,导致无法选举 Primary。自动化巡检中应把仲裁节点的进程存活、网络延迟纳入监控,但不要把它当作数据备份对象。

五、组件关系与自动化运维关注点

把上述组件放在一起,可以得到一张完整的集群拓扑关系图。下图展示了分片集群中客户端、mongos、config server 副本集、shard 副本集以及仲裁节点的连接关系,并标注了自动化运维中最需要关注的观测点。

MongoDB 分片集群组件关系与运维观测点 客户端应用 连接串含多个 mongos Mongos 路由层(无状态,可水平扩展) mongos-1 mongos-2 mongos-3 请求路由 Config Server 副本集(CSRS) 存储 chunk / shard / 集合元数据 cfg-1 cfg-2 cfg-3 元数据不可用 → 路由失效 读取元数据 Shard A 副本集 chunk 范围:min ~ 某分片键值 Primary Secondary Arb Shard B 副本集 chunk 范围:另一分片键区间 Primary Secondary Arb 按 chunk 路由 自动化运维观测点 副本集角色 rs.status() / db.hello() 复制延迟 rs.printSlaveReplicationInfo() Chunk 均衡 sh.status() / balancer 状态 mongos 连接与延迟 connPoolStats / serverStatus Config 元数据一致性 config 副本集健康检查 分片键与热点 chunk 分布 / 读写倾斜 仲裁节点存活 进程 / 网络 / 投票状态 写关注与读偏好 w / j / readPreference

六、自动化运维中的关键判断

在实际自动化脚本中,需要根据组件角色做出不同处理。例如:

  • 备份:应优先从 Secondary 节点执行 mongodump 或文件系统快照,避免影响 Primary 写入。脚本需先通过 db.hello().secondary 判断目标节点是否为从节点。
  • 索引构建:在副本集上建议使用滚动方式,先在 Secondary 上建索引,再切换 Primary,避免全量锁表影响业务。
  • 分片扩容:新增 shard 后,需要触发 balancer 迁移 chunk。自动化流程应检查 sh.status() 中 chunk 分布是否均衡,而不是仅确认 shard 已加入。
  • 故障切换:副本集自动选举期间,应用连接串应配置 retryWrites=true 和合理的 serverSelectionTimeoutMS,避免短暂不可用导致请求全部失败。
一个实用的巡检顺序:先确认 config server 副本集健康,再确认各 shard 副本集有 Primary,然后检查 mongos 到 config 和 shard 的连通性,最后观察 chunk 分布与复制延迟。这个顺序符合“元数据 → 数据 → 路由 → 均衡”的依赖关系。

总结来看,副本集解决高可用,分片集群解决水平扩展,配置服务器保存集群元数据,路由节点提供无状态入口,仲裁节点以低成本参与选举。自动化运维的核心,不是记住这些名词,而是理解每个组件的状态如何影响整体可用性,并在脚本中动态获取角色、判断健康、选择正确的操作目标。