首页/数据/NoSQL 速查/分片集群概念与分片键
MongoDB99 条

分片集群概念与分片键

分片集群由 mongos 路由、config 配置库与多个 shard 组成;分片键决定数据分布,范围分片适合区间查询,哈希分片更均匀。

NoSQL 速查数据更新于 2026-10-13

是什么

分片(sharding)把一个大集合按分片键切成若干段(chunk),分散到多个 shard 上。集群由三类角色组成:mongos 负责接收客户端请求、按分片键路由;config server 保存集群元数据(分片键、chunk 分布、均衡状态);shard 承载真实数据,每个 shard 本身通常是一个副本集。分片键在集合创建后不能随意改,因此它是设计阶段的一次性决策。

基本信息

集群角色mongos 路由、config server 元数据、shard 数据节点(副本集)
开启分片sh.enableSharding("app")
分片集合sh.shardCollection("app.orders", { customerId: "hashed" })
查看状态sh.status()、db.orders.getShardDistribution()、sh.isBalancerRunning()
均衡器sh.startBalancer() / sh.stopBalancer() / sh.setBalancerState(true)

典型使用场景

  • 单机容量上限:数据量或写入量超过单个副本集能承载的范围时按分片键水平切分
  • 热点写入分散:单调递增的分片键会把写压力集中在最后一段,改用哈希分片可打散
  • 数据本地化:用 zone 把特定范围的数据固定在某个机房或高配机型上
  • 读写隔离:把冷数据迁到低配分片,热数据留在高配分片
  • 并行聚合:无分片键的统计查询会广播到所有分片各自计算,再在 mongos 汇总

启用分片与观察

启用分片与观察
sh.enableSharding("app")                       # 对数据库开启分片
sh.shardCollection("app.orders", { customerId: "hashed" })  # 哈希分片,写入更均匀
sh.shardCollection("app.logs", { tenantId: 1, ts: 1 })       # 复合范围分片键
sh.status()                                     # 查看集合分片状态与 chunk 分布
db.orders.getShardDistribution()                # 逐分片看数据量与 chunk 数
sh.isBalancerRunning()                          # 均衡器是否在工作
sh.stopBalancer()                               # 大变更期间可临时停均衡,减少抖动

查询路由行为

查询条件路由结果代价
分片键等值定向到单个分片最低
分片键范围命中少量分片较低
不含分片键广播到全部分片后归并随分片数线性上升
不含分片键的排序各分片排序后在 mongos 归并内存与网络压力明显
跨分片聚合各分片局部聚合后汇总受最慢分片影响
分片键基数太低(如状态字段)会导致 chunk 无法继续拆分、形成超大 chunk;单调递增的分片键(自增 ID、时间戳)会把写入集中到最后一段。优先选择高基数、写入分散、且常用在查询条件里的字段。
分片键是查询路由的前提,也是文档必须携带的字段:设计时要一起看写入分布与高频查询条件,两边的诉求常需要复合分片键来平衡;MongoDB 5.0+ 提供了 reshardCollection 用于变更分片键,但成本高于一次选对。

易错点

  • 上线后才改分片键:变更需要重写整个集合数据,代价远高于设计阶段多花一天做验证
  • 只按查询方便选分片键、忽略写入分布,结果写入全压在一个分片上,扩容无收益
  • 在分片集群上通过直连 shard 做业务读写:绕过了 mongos 的元数据路由,会读到不完整数据
  • 均衡器在业务高峰期搬运 chunk 抢占 IO,变更或大促前应确认均衡行为已在计划内

数据来源与参考

  • MongoDB Manual: Sharding
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌