启用Balancer功能并进行预分片,可以有效解决大部分数据都写入到单个分片上(数据倾斜)的问题。
开启Balancer
如果Balancer处于关闭状态,或者还未达到Balancer窗口设置的时间段,您可以开启或者临时取消Balancer的窗口期,以立即开始数据均衡。
连接MongoDB分片集群实例。
在mongos节点命令窗口中,切换至config数据库。
use config根据实际情况,执行如下命令。
开启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()命令确认预分片的效果。