首页/数据/NoSQL 速查/分片键选择与热点规避
选型与架构50 条

分片键选择与热点规避

分片键决定数据分布与查询路由:基数要高、取值频率要均匀、避免单调递增。MongoDB 支持范围与散列两类分片键,散列键能打散写入、代价是范围查询要扇出到所有分片核对。

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

分片键决定两件事

分片键同时决定数据分布与查询路由:基数要高、取值频率要均匀、避免单调递增。它一旦选定就很难更改,所以要在上线前按真实查询清单验证,而不是等数据量上来再调整。

范围键与散列键的取舍

范围分片键保留区间有序性,便于范围查询与就近路由,但单调递增的键会把写入集中到最后一个分片;散列分片键能把写入打散,代价是范围查询需要扇出到所有分片核对。按时间检索多、又要求写入分散时,可以评估复合分片键。

基本信息

高基数候选值足够多,避免少数分片承载大部分数据
低频率单个取值不集中,热点取值不适合做分片键
非单调写入不落在同一区间,散列键可缓解单调键的写入集中
改写成本分片键需要重建集合或迁移数据才能调整
适用范围以分片集群为例,思路对同类系统通用

启用分片与选择分片键

启用分片与选择分片键
sh.enableSharding("app")

// 散列分片键:写入分散,范围查询需要扇出
sh.shardCollection("app.events", { deviceId: "hashed" })
sh.status()

// 复合分片键:先按租户散列,再按时间排序
sh.shardCollection("app.events", { tenantId: "hashed", ts: 1 })

// 查看各分片的数据分布,确认是否均衡
db.events.getShardDistribution()

典型使用场景

  • 新集合分片:按访问模式选择范围键或散列键
  • 热点治理:写入集中的集合改用散列键或复合键
  • 多租户隔离:用租户标识作为分片键前缀,减少跨分片查询
  • 容量规划:结合分片键分布估算各分片的增长
  • 上线验证:按查询清单确认常用查询能命中分片键

分片键形态与代价

分片键形态优势代价
范围键(如时间)范围查询与就近路由高效单调递增会把写入压到单个分片
散列键写入分布均匀范围查询需要扇出到所有分片
复合键兼顾分布与局部有序设计复杂度上升
低基数键实现简单分片间无法均衡,容易形成热点
分片键影响路由与均衡:范围查询在散列键上需要访问所有分片;按时间检索多又要求按租户隔离时,复合分片键往往更合适。
用自增 ID 或时间戳作为唯一分片键会把写入集中到单个分片形成热点;分片键选择后修改成本很高,通常要重建集合并迁移数据。

易错点

  • 用自增 ID 或时间戳作分片键会把写入集中到单个分片,形成单调递增热点
  • 分片键修改成本高,需要专用命令或重建集合迁移,上线前先按查询清单验证
  • 选低基数键会让分片间无法均衡,少数分片承载大部分数据
  • 常用查询不带分片键时会扇出到所有分片,性能退化到与单机同一级别

数据来源与参考

  • MongoDB Manual: Shard keys
  • MongoDB Manual: Hashed sharding
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌