2. MongoDB生产环境架构梳理
做生产故障演练,第一步不是急着敲命令,而是先把“故障会落在哪一层、影响谁”这件事画清楚。MongoDB 的生产部署通常由四类角色组成:副本集(Replica Set)、分片(Shard)、配置服务器(Config Server,简称 CSRS)、路由节点(mongos)。它们不是并列的四个组件,而是有明确的依赖层级——副本集是最小的高可用单元,分片集群是在副本集之上叠加的横向扩展结构,配置服务器保存集群的“地图”,mongos 则是客户端唯一入口。理解这层依赖关系,才能判断一次故障是“局部抖动”还是“全局不可用”。
一、副本集:高可用的最小单元
副本集由多个持有相同数据的 mongod 组成,典型为三节点:一个 Primary 负责读写,其余 Secondary 通过 oplog 持续复制。当 Primary 不可达,剩余节点发起选举,选出新 Primary,客户端在驱动层自动重连。副本集的关键参数是 writeConcern 和 readConcern:w:1 只要求 Primary 确认,故障时可能丢最近写入;w:"majority" 要求多数节点确认,能保证已确认写入不丢,但延迟更高。生产环境通常写关注用 majority,读关注按业务选择 local 或 majority。
副本集的故障影响面相对可控:单节点宕机,只要多数节点存活,集群仍可读写;但如果多数节点同时不可用(例如同机架断电、网络分区导致少数派孤立),Primary 会降级为 Secondary,整个副本集进入只读甚至不可写状态。这是演练中必须覆盖的场景。
二、分片集群:横向扩展的骨架
当单副本集容量或写入吞吐达到瓶颈,就引入分片。每个分片本身是一个副本集,负责一部分数据。数据按分片键(shard key)切分成 chunk,由 balancer 在分片间迁移。分片键选择直接决定数据分布是否均匀:范围分片适合范围查询但易热点,哈希分片分布均匀但范围查询会广播到所有分片。分片集群的故障影响面是“部分可用”:某个分片的主节点故障,只影响该分片上的数据读写,其他分片不受影响;但如果某个分片整体不可用,涉及该分片键范围的查询会失败或超时。
三、配置服务器:集群的“地图”
配置服务器在 MongoDB 3.4 之后必须以副本集形式部署(CSRS),通常三节点。它不存业务数据,只存集群元数据:分片列表、chunk 分布、分片键定义、balancer 状态等。mongos 启动时从配置服务器加载元数据,之后缓存并增量更新。配置服务器的故障影响面非常特殊:它不直接参与业务读写,但一旦不可用,mongos 无法刷新元数据,新分片、chunk 迁移、balancer 都会停滞;如果配置服务器多数节点丢失,整个集群可能无法启动或无法路由。因此配置服务器的备份和恢复优先级极高。
四、路由节点 mongos:客户端唯一入口
mongos 是无状态的路由进程,客户端连接 mongos,由它根据分片键将请求转发到对应分片,并聚合结果。mongos 本身不持久化数据,可以水平扩展多个实例,前面挂负载均衡。mongos 故障的影响面是“连接层”:单个 mongos 宕机,已连接的客户端会断开重连到其他 mongos;但如果所有 mongos 都不可用,客户端就无法访问集群。mongos 的另一个关键点是它依赖配置服务器,配置服务器不可达时,mongos 可能无法启动或无法处理需要元数据的请求。
五、四类角色的依赖关系与故障传导
把上面四层串起来看,依赖方向是:客户端 → mongos → 配置服务器 + 分片。mongos 同时依赖配置服务器(拿元数据)和分片(拿数据)。这意味着故障传导有两条路径:一条是“入口路径”,mongos 全挂则客户端不可达;另一条是“元数据路径”,配置服务器不可用则 mongos 无法正确路由,即使分片本身健康,新请求也可能失败。分片内部的副本集故障则只影响该分片的数据范围,属于局部影响。
演练时可以用一个简单的判断表来定位故障层级:客户端报“no mongos available”说明入口层问题;报“cannot refresh metadata”或 balancer 不工作说明配置服务器层问题;报某个分片键范围查询超时说明分片层问题;报“not primary”或写入被拒说明副本集层问题。这个判断顺序能帮你在演练中快速缩小范围。
六、演练前的架构清单
在开始任何故障演练之前,建议先整理一份当前环境的架构清单,至少包含以下字段:
| 角色 | 实例地址 | 副本集名称 | 当前角色 | 关键参数 | 故障影响面 |
|---|---|---|---|---|---|
| mongos | 10.0.1.11:27017 | — | 路由 | 无状态 | 单点断开可重连 |
| mongos | 10.0.1.12:27017 | — | 路由 | 无状态 | 单点断开可重连 |
| CSRS | 10.0.2.11:27019 | csrs | Primary | w:majority | 元数据停滞 |
| CSRS | 10.0.2.12:27019 | csrs | Secondary | — | 同上 |
| Shard-1 | 10.0.3.11:27018 | shard1 | Primary | w:majority | 范围 A 受影响 |
| Shard-2 | 10.0.4.11:27018 | shard2 | Primary | w:majority | 范围 B 受影响 |
理解架构不是为了背概念,而是为了在故障发生时能立刻回答三个问题:故障在哪个角色上?这个角色的依赖方是谁?影响面是全局、局部还是仅连接层?把这三个问题对应到副本集、分片、配置服务器、mongos 四层上,后续的演练设计、故障注入和恢复验证就有了清晰的坐标系。