MongoDB跨IDC分片集群容灾需显式配置副本集tags、priority和votes,应用层控制读写路由;mongos不复制数据,写始终发往Primary所在IDC;config server必须跨IDC部署为CSRS副本集。

跨IDC部署 MongoDB 分片集群时,不能靠默认复制机制自动实现“跨IDC数据复制”——mongos 不负责复制,shard 本身必须是副本集(Replica Set),而跨IDC的容灾能力完全依赖于这个副本集的成员分布和优先级配置。
副本集节点必须跨IDC部署,且不能只靠 priority 控制主节点位置
把一个副本集的三个节点分别放在 IDC-A、IDC-B、IDC-C,不等于就实现了“跨IDC容灾”。MongoDB 的选举逻辑会优先选 priority 最高的可投票节点为 Primary,但如果该节点所在 IDC 网络中断,其他 IDC 的 Secondary 节点可能因心跳超时无法及时触发新选举(尤其当 electionTimeoutMillis 设置过大或网络抖动频繁时)。
-
priority只影响选举倾向,不强制绑定物理位置;必须配合tags和读写偏好(readPreference/writeConcern)使用 - 每个节点需显式配置
tags,例如:{"idc": "shanghai"}、{"idc": "beijing"} - 在应用连接字符串中指定
readPreference=secondaryPreferred&tagSets=[{"idc":"beijing"}],才能让读流量落到本地 IDC -
writeConcern应设为{w: "majority", wtimeout: 5000},避免因跨IDC延迟导致写入卡住
mongos 无法跨IDC路由写请求,所有写都发往当前 Primary 所在 IDC
这是最容易误解的一点:分片集群里,mongos 只做查询路由和结果合并,它不会、也不能把一条 insert 拆成多份发到不同 IDC。写操作永远只发给当前 Shard 的 Primary —— 所以如果 Primary 在 IDC-A,所有对该 Shard 的写请求都会经过 IDC-A 的网络链路,IDC-B 的节点只是异步同步 oplog。
- 没有“跨IDC写负载均衡”这种事,MongoDB 不支持多写(multi-master)
- 若要求某类业务写入就近 IDC,只能靠应用层拆分集合(如按
region字段分片),并确保对应分片的 Primary 固定落在目标 IDC(用members[n].priority+members[n].votes控制) - 强制迁移 Primary 的命令是
rs.stepDown(),但生产环境慎用;更稳妥的是在初始化副本集时就规划好节点顺序和 priority
配置服务器(Config Server)必须也跨IDC,且必须是副本集(csrs)
很多人只关注 Shard 副本集跨IDC,却忽略配置服务器。一旦 config server 全部挂在一个 IDC,整个集群元数据不可写,mongos 就会拒绝所有 DDL 操作(如添加分片、修改分片键),甚至部分写操作也会失败(取决于 writeConcern 配置)。
-
config server必须部署为三节点副本集(csrs),且至少两个节点跨 IDC - 不能复用 Shard 的副本集节点——配置服务器有独立角色,混部会增加故障耦合风险
- 启动时必须指定
--configsvr参数,且连接字符串中需用configDB=cs0/...显式指向该副本集 - 检查是否生效:连接任意
mongos后执行sh.status(),确认config server状态为PRIMARY且成员列表包含多 IDC 节点
真正难的不是配置命令怎么写,而是判断哪些节点该放哪、priority 和 votes 怎么配才能既满足多数派写入,又不让某个 IDC 成为单点瓶颈——这需要结合你的网络延迟实测值、业务读写比例、以及故障恢复 SLA 来反复调优,而不是套模板。











