资讯

展开

MongoDB 之chunk分裂之autosplit

作者:快盘下载 人气:

//

MongoDB 之chunk分裂之autosplit

//

在MongoDB分片集群中,使用分片键将数据分割成连续的数据块,这种数据块称之为chunk。

默认的chunk的大小是64MB,随着数据的写入,chunk的数据会越来越多,当chunk的数量超过这个默认值的时候,如果再对集合进行insert和update操作,则会触发chunk的分裂操作,也就是chunk的split操作。

这里需要注意一点,如果我们关闭了chunk的autosplit属性,那么这个chunk就不会自动分裂。当我们重新打开这个autosplit属性的时候,MongoDB并不会直接帮助我们进行autosplit,这里必须要有insert和update来触发这个split的动作。

chunk分裂的过程类似下面这样:

MongoDB 之chunk分裂之autosplit

如图,一个64.2MB的chunk分裂成了两个32.1MB的chunk。

如何设置chunk的默认大小?

如果你不想chunk频繁的进行分裂,可以适当调大这个chunk的默认大小,但是也不能太大,否则后续每个chunk数量不均匀的时候,搬迁的时候会有压力。

按照官网的说法,默认的64MB能够满足大多数的业务需求,一般不建议改,如果确实由于业务需求,需要改动,可以使用下面的办法:

1、连接到mongos上

2、执行:

use config
db.settings.save( { _id:"chunksize", value: <sizeInMB> } )

其中,value的单位是MB,如果要改成128M,直接value=128即可。

如何开启和关闭chunk的autosplit操作?

方法一:

使用sh.disableAutoSplit和sh.enableAutoSplit命令来关闭和打开chunk的autosplit

mongos> db.settings.find()
{ "_id" : "autosplit", "enabled" : true }
mongos> sh.disableAutoSplit()
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
mongos> db.settings.find()
{ "_id" : "autosplit", "enabled" : false }
mongos> sh.enableAutoSplit()
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
mongos> db.settings.find()
{ "_id" : "autosplit", "enabled" : true }

方法二:

如果你的mongodb是4.2及以上版本,可以使用balancer的开关命令来开关chunk的autosplit操作:

mongos> db.settings.find()
{ "_id" : "balancer", "mode" : "full", "stopped" : false }
{ "_id" : "autosplit", "enabled" : true }
//关闭balancer
mongos> sh.stopBalancer()
{
        "ok" : 1,
}

mongos> db.settings.find()
{ "_id" : "balancer", "mode" : "off", "stopped" : true }
{ "_id" : "autosplit", "enabled" : false }
mongos> 
mongos> 

//开启balancer
mongos> sh.startBalancer()
{
        "ok" : 1,
}
mongos> db.settings.find()
{ "_id" : "balancer", "mode" : "full", "stopped" : false }
{ "_id" : "autosplit", "enabled" : true }

方法三:

直接使用save命令,修改config数据库下面的settings表:

mongos> use config
mongos> db.settings.find()
{ "_id" : "autosplit", "enabled" : true }

mongos> db.settings.save({ "_id" : "autosplit", "enabled" : false })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
mongos> db.settings.find()
{ "_id" : "autosplit", "enabled" : false }

mongos> db.settings.save({ "_id" : "autosplit", "enabled" : true })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
mongos> db.settings.find()
{ "_id" : "chunksize", "value" : 1 }
{ "_id" : "balancer", "mode" : "full", "stopped" : false }
{ "_id" : "autosplit", "enabled" : true }

chunk split的速度怎么样?如果业务有写入会不会影响?

官方文档上的说明: 也就是说,这个操作是元数据层面的一个高效的操作,按理说不会对业务的写入产生影响。

实际操作中,在4.2.14版本的MongoDB中,关闭balancer(也就意味着关闭了autosplit),导入一个包含9亿条数据的集合,这个数据集合一共只有2个chunk,每个chunk大概100多G数据。

然后开启balancer(也就意味着开启了autoplit操作),进行数据写入,整个autosplit操作在30s以内就完成了,autosplit之后,整个集合的chunk数变成了9000左右。在此期间,数据写入没有报错,所以可以判定这个autosplit的操作整体对写入没有影响。

shard key: { "number" : 1 }
               unique: false
               balancing: true
               chunks:
                  test1   1

autosplit之后的结果:
shard key: { "number" : 1 }
               unique: false
               balancing: true
               chunks:
                  test1   9546

当然,如果你想看shard的chunk拆分具体情况,可以使用下面的命令来查看:

mongos> db.test.getShardDistribution()

Shard test at test1/xxx.xxx.xxx.xx:port
 data : xxx MiB docs : xxxxx chunks : xxxx
 estimated data per chunk : xxxx MiB
 estimated docs per chunk : xxxxx

Totals
 data : xxxxx MiB docs : xxxxx  chunks : xxxx
 Shard test contains 100% data, 100% docs in cluster, avg obj size on shard : xxxxx

加载全部内容

相关教程
猜你喜欢
用户评论
快盘暂不提供评论功能!