全部产品
Search
文档中心

数据传输服务 DTS:如何处理分片集群架构的MongoDB数据分布不均衡

更新时间:Sep 23, 2026

启用Balancer功能并进行预分片,可以有效解决大部分数据都写入到单个分片上(数据倾斜)的问题。

开启Balancer

如果Balancer处于关闭状态,或者还未达到Balancer窗口设置的时间段,您可以开启或者临时取消Balancer的窗口期,以立即开始数据均衡。

  1. 连接MongoDB分片集群实例。

  2. 在mongos节点命令窗口中,切换至config数据库。

    use config
  3. 根据实际情况,执行如下命令。

    • 开启Balancer功能

      sh.setBalancerState(true)
    • 临时取消Balancer的窗口期

      db.settings.updateOne( { _id : "balancer" }, { $unset : { activeWindow : true } } )

预分片

MongoDB支持范围分片和哈希分片两种分片方式,预分片可以使Chunk(块)的取值尽可能分散到多个Shard节点中,从而在DTS数据同步或迁移过程中实现负载尽可能均衡。

哈希分片

使用numInitialChunks参数,方便快捷地实现预分片。取值默认为分片数×2,最大可以设置为分片数×8192。更多信息,请参见sh.shardCollection()。

sh.shardCollection("phonebook.contacts", { last_name: "hashed" }, false, {numInitialChunks: 16384})

范围分片

  • 如果源MongoDB也是分片集群架构,则可以通过config.chunks中的数据来获取源MongoDB对应分片表的Chunk范围,并作为后续预分片命令中<split_value>的取值参考。

  • 如果源MongoDB是副本集,则只能通过find命令明确分片键的具体范围,然后再设计合理的分裂点。

    # 获得片键的最小值
    db.<coll>.find().sort({<shardKey>:1}).limit(1)
    # 获得片键的最大值
    db.<coll>.find().sort({<shardKey>:-1).limit(1)

命令格式

说明

以splitAt命令为例,更多信息,请参见sh.splitAt()、sh.splitFind()、Split Chunks in a Sharded Cluster。

sh.splitAt("<db>.<coll>", {"<shardKey>":<split_value>})

示例语句

sh.splitAt("test.test", {"id":0})
sh.splitAt("test.test", {"id":50000})
sh.splitAt("test.test", {"id":75000})

在完成预分片的操作后,您可以在mongos节点执行sh.status()命令确认预分片的效果。