分片集群必须严格按“config server → shard → mongos”顺序启动并验证:config server需先以--configsvr参数启动、完成rs.initiate()初始化;shard节点须带--shardsvr参数且副本集已就绪;mongos再通过--configdb连接已初始化的config副本集,顺序错误或参数缺失将导致连接失败。

分片集群不是“装完就能用”的架构,必须按角色逐层启动、验证、关联,顺序错一步,mongos 就连不上 configsvr,所有后续操作都会卡在 sh.addShard() 报错。
mongod 启动时必须明确指定角色参数
每个 mongod 实例启动前,得先区分它是 shard、configsvr 还是普通节点。MongoDB 4.4+ 强制要求显式声明角色,否则拒绝启动:
-
shardsvr:仅用于分片数据节点,必须配合replSet使用(不能单节点) -
configsvr:仅用于配置服务器,且replSet名称不能和任何 shard 的replSet名称重复 - 没加这两个参数的
mongod,哪怕端口、目录都对,mongos也会报failed to connect to server
示例(config server 启动命令):
mongod --port 27019 --dbpath /data/config --replSet cfg-rs --configsvr --bind_ip_all
注意:--configsvr 是必需参数,不是可选开关;--replSet 值(如 cfg-rs)要和后续初始化副本集时一致。
config server 必须先完成副本集初始化再启动 mongos
mongos 启动时会立即连接 configsvr 并读取元数据。如果 configsvr 节点还没完成 rs.initiate(),mongos 会直接退出并报错 Failed to load config database。
- 三台
configsvr全部启动后,只用连其中一台执行rs.initiate(),不用每台都 init - 初始化时必须传入完整成员列表(host + port),不能只写 localhost —— MongoDB 5.0+ 拒绝纯
localhost配置 -
mongos的--configdb参数必须指向这个已初始化的副本集名称和任意一个成员,例如:cfg-rs/cfg1:27019,cfg2:27019,cfg3:27019
添加 shard 时常见连接失败原因
sh.addShard("rs0/shard1:27017,shard2:27017,shard3:27017") 执行失败,90% 是网络或角色问题:
- shard 节点的
mongod没加--shardsvr,会被mongos拒绝识别 - shard 副本集未初始化(
rs.initiate()没执行),或初始化后主节点还没选出来(rs.status().myState !== 1) -
mongos和 shard 节点之间 DNS 不通,或防火墙拦了端口(默认 27017,不是 mongos 的端口) - shard 副本集名称(
replSet)和sh.addShard()字符串里写的不一致(大小写敏感)
分片键选择直接影响后续扩容能力
启用分片后,sh.enableSharding("db") 和 sh.shardCollection("db.coll", {"key": 1}) 一旦执行,分片键就不可更改。选错会导致数据倾斜、chunk 搬迁卡死:
- 范围分片(
{"ts": 1})适合时间序列,但容易热点(新数据全写到同一 shard) - 哈希分片(
{"uid": "hashed"})能均匀分布,但不支持范围查询({$gt: ...}) - 复合片键(
{"region": 1, "uid": "hashed"})兼顾路由与分布,但索引体积增大 - 字段必须已有对应索引,否则
shardCollection直接报错can't shard collection without an index
真正麻烦的不是搭建过程本身,而是 config server 副本集初始化后忘记设 writeConcernMajorityJournalDefault: true —— 这个配置缺失会导致后续 chunk 迁移失败,错误日志里只显示 moveChunk error,根本看不出根源。


















