MongoDB在单节点中也可以做复制集,但是仅限于测试实验,最大的好处就是部署方便快速,可以随便添加新节点,节省资源。在这里我使用的是MongoDB 3.2版本进行复制集实验(但MongoDB配置文件使用的是老版本格式)。
为什么要手动分片?
MongoDB默认都是自动分裂和自动平衡的,前面已经介绍过什么是数据块分裂和数据块平衡了。在MongoDB自动分裂和平衡的过程中会多少带来一些IO和其他硬件资源的消耗。那么为了减少这些消耗,可能会建议使用手动分片,当然目前Mongodb自动分片也是可以满足绝大部分的需求。那么对于手动分片的一个前提就是:
1、 关闭自动平衡,关闭auto balance。
2、 充分了解数据,并对数据进行预先划分,需要知道对片键的选用以及数据片键里面存储的内容。
手动分片实例
如果想进行手动分片操作的话,需要在向集群中添加分片之后进行手动分片操作。关于分片集群的搭建与向集群中添加分片的操作前面介绍过了。这里大概说一下向集群中添加分片的步骤如下:
步骤一、连接到mongos
1 2 3 4 |
[root@localhost ~]# mongo 192.168.60.10:27017 MongoDB shell version: 3.2.0 connecting to: 192.168.60.10:27017/test mongos> |
步骤二、添加2个点节点Shard(必须在admin数据库下进行)
1 2 3 4 5 6 |
mongos> use admin switched to db admin mongos> sh.addShard( "192.168.60.10:27018") { "shardAdded" : "shard0000", "ok" : 1 } mongos> sh.addShard( "192.168.60.10:27028") { "shardAdded" : "shard0001", "ok" : 1 } |
步骤三、为集群数据库开启分片
1 |
mongos> sh.enableSharding("shardtest") |
步骤四、对一个集合进行分片
1 |
mongos> sh.shardCollection("shardtest.user",{userid:"hashed"}) |
手动分片操作步骤如下:
步骤一、关闭自动平衡
1 2 3 |
关闭方式:sh.stopBalancer() 启动方式:sh.startBalancer() 检查状态:sh.isBalancerRunning() |
步骤二、分片手动切割
1 2 3 4 5 6 7 8 |
mongos> use admin switched to db admin mongos> for (var x=97;x<97+26;x++){ for( var y=97;y<97+26;y+=6) { var prefix=String.fromCharCode(x)+String.fromCharCode(y); db.runCommand({split:"shardtest.user",middle:{userid:prefix}}); }} |
大概的意思就是,第一个循环就是x=97,如果x小于123的话,x就加1。第二个循环就是y等于97,y小于123的话,y等于y+6。然后写一个变量prefix等于x+y的值,而String.fromCharCode(x)就是把x格式化为字符串格式。最后执行命令split,分割shardtest.user集合。
步骤三、手动移动分割块
就是将已经分割好的数据块,手动分割移动到shard上面。下面的命令是定义了一个变量,而变量里面存的内容是一个LIST,列表里面存的都是我们后端shard成员地址以及对应的端口。
1 2 3 4 5 6 7 8 |
mongos> var shserver=[ "192.168.60.10:27018", "192.168.60.10:27028", "192.168.60.10:27018", "192.168.60.10:27028", "192.168.60.10:27018", "192.168.60.10:27028" ] |
然后还是执行一个循环,同分片切割使用的循环差不多,不同的是执行命令的时候使用moveChunk,然后找到打到不同的shard节点(shserver[(y-97)/6])。
1 2 3 4 5 6 7 8 |
mongos> use admin switched to db admin mongos> for (var x=97;x<97+26;x++){ for( var y=97;y<97+26;y+=6) { var prefix=String.fromCharCode(x)+String.fromCharCode(y); db.runCommand({moveChunk:"shardtest.user",find:{userid:prefix}, to:shserver[(y-97)/3]}); }} |
PS:以上内容暂时不适合使用,仅供做做实验让你更加明白Mongodb数据块迁移原理。当然如果后续有更详细的关于自动分片的内容会继续补上。