Config Server 必须是三节点CSRS副本集而非单节点或主从镜像,因其存储分片集群全部元数据,需通过w:"majority"写入、主节点强读、全数据节点参与保障强一致性。
Config Server 为什么必须是副本集,而不是单节点或主从镜像
因为 Config Server 存的是整个分片集群的元数据——库/集合是否分片、片键是什么、每个 chunk 在哪个分片上、shard key 范围映射……这些信息一旦出错或丢失,
就会路由错、查不到数据、甚至写入丢弃。早期 MongoDB 3.2 之前用“镜像模式”(mirror mode)的 Config Server 是单点+只读从库,不参与选举、不保证 oplog 同步顺序,主挂了从可能延迟数秒甚至丢变更,导致元数据不一致,集群直接不可用。
从 3.4 开始强制要求 Config Server 必须是
(Config Server Replica Set),即一个标准的三节点副本集,所有写入都走主节点 +
写关注,oplog 强序复制,选举机制保障高可用——这不是“可选优化”,而是架构级硬性约束。
CSRS 的强一致性到底体现在哪几个关键操作上
不是所有读写都自动强一致,得看客户端怎么用。真正起作用的是以下三个联动环节:
向 Config Server 写入新 chunk 拆分结果时,必须等多数节点落盘才返回成功,否则拒绝拆分,避免“一半知道、一半不知道”
启动或刷新配置缓存时,会从 CSRS 主节点读取最新
和
,不接受
—— 你不能容忍它读到旧的分片状态
执行
或
时,驱动内部会隐式使用
,这是由
模块强制注入的,绕不开
部署 CSRS 时最容易被忽略的三个配置陷阱
很多人按副本集常规方式配完就 init,结果集群跑几天后出现“找不到分片”“chunk 迁移卡住”之类问题,往往栽在这几个点上:
没关
:CSRS 对延迟敏感,THP 会导致 mongod 偶发几百毫秒停顿,选举超时失败;Linux 下必须运行
设太大:默认 100ms 可接受,但有人为“提升吞吐”改成 500ms,结果在主节点 crash 时,CSRS 可能丢失最近半秒的元数据变更,造成 config 数据不一致
成员 host 写了
或内网 IP 却没配
:mongos 连不上某个 config 节点,会静默降级为只读缓存,后续元数据更新就不同步了——必须全部用可互通的域名或真实 IP,且每个节点
明确包含该地址
为什么不能用仲裁节点(arbiter)凑 CSRS 的三节点
可以加,但绝对不推荐。CSRS 的每个节点都要参与元数据读写和心跳投票,仲裁节点不存数据、不写 oplog、不服务读请求,只投一票。一旦主节点压力大或网络抖动,它可能把票投给一个还没同步完最新 config 变更的从节点,新主上线后
读到的就是过期路由表。
MongoDB 官方文档明确建议:CSRS 所有成员都应是数据承载节点(即
且无
)。最小安全配置就是 3 个真副本,哪怕其中一个是低配——元数据体积小,I/O 压力远低于数据分片,资源不是瓶颈,一致性才是。
CSRS 的强一致性不是靠“多写几份”实现的,而是靠“写入路径全链路强制 majority 确认 + 读取路径强制主节点兜底 + 成员角色严格限定”。漏掉任意一环,表面看着集群在跑,实际元数据已在悄悄漂移。
mongosCSRSw: "majority"mongosmongosconfig.databasesconfig.collectionssecondaryPreferredsh.moveChunksh.splitAtwriteConcern: { w: "majority" }shardingtransparent_hugepageecho never > /sys/kernel/mm/transparent_hugepage/enabledstorage.journal.commitIntervalMslocalhostnet.bindIpAll: truebindIpmongospriority: 1arbiterOnly: true