[关闭]
@52fhy 2015-09-20T15:50:21.000000Z 字数 3322 阅读 454

MongoDB——第六天 分片技术

mongo


在mongodb里面存在另一种集群,就是分片技术,跟sql server的表分区类似,我们知道当数据量达到T级别的时候,我们的磁盘,内存就吃不消了,针对这样的场景我们该如何应对。

一:分片

mongodb采用将集合进行拆分,然后将拆分的数据均摊到几个片上的一种解决方案。图例分析:

从服务器1        从服务器2
        \         /
    路由服务器mongods  <——> config服务器   
            |
            |
          客户端

下面我对这张图解释一下:
客户端:客户端肯定说,你数据库分片不分片跟我没关系,我叫你干啥就干啥,没什么好商量的。
mongos:首先我们要了解”片键“的概念,也就是说拆分集合的依据是什么?mongos就是一个路由服务器,它会根据管理员设置的“片键”将数据分摊到自己管理的mongod集群,数据和片的对应关系以及相应的配置信息保存在"config服务器"上。
从服务器:一个普通的数据库实例,如果不分片的话,我们会直接连上mongod。

二:实战

首先我们准备4个mongodb程序,我这里是均摊在C,D,E,F盘上,当然你也可以做多个文件夹的形式(下面将采用目录的形式mongodb、mongodb2、mongodb3、mongodb4对应C,D,E,F盘)。

mongodb   ---config  --port 2222
mongodb1  ---mongos  --port 3333
mongodb2  ---mongod  --port 4444
mongodb3  ---mongod  --port 5555

1:开启config服务器
先前也说了,mongos要把mongod之间的配置放到config服务器里面,理所当然首先开启它,我这里就建立2222端口。

  1. D:\Projects\mongodb\bin>mongod --dbpath=D:\Projects\mongodb\db --port 2222

2: 开启mongos服务器
这里要注意的是我们开启的是mongos,不是mongod,同时指定下config服务器,这里我就开启D盘上的mongodb,端口3333。

  1. D:\Projects\mongodb2\bin>mongos --port 3333 --configdb=127.0.0.1:2222

3:启动mongod服务器
对分片来说,也就是要添加片了,这里开启E,F盘的mongodb,端口为:4444,5555。

  1. mongod --dbpath=D:\Projects\mongodb3\db --port 4444
  2. mongod --dbpath=D:\Projects\mongodb4\db --port 5555
  3. 2015-07-04T10:34:15.394+0800 I NETWORK [initandlisten] waiting for connections on port 4444
  4. 2015-07-04T10:35:35.372+0800 I NETWORK [initandlisten] waiting for connections on port 5555

4: 服务配置
哈哈,是不是很兴奋,还差最后一点配置我们就可以大功告成。
<1>先前图中也可以看到,我们client直接跟mongos打交道,也就说明我们要连接mongos服务器,然后将4444,5555的mongod交给mongos,添加分片也就是addshard()。

  1. D:\Projects\mongodb\bin>mongo 127.0.0.1:3333/admin
  2. connecting to: 127.0.0.1:3333/admin
  3. mongos>
  4. mongos> db.runCommand({"addshard":"127.0.0.1:4444","allowLocal":true})
  5. { "shardAdded" : "shard0000", "ok" : 1 }
  6. mongos> db.runCommand({"addshard":"127.0.0.1:5555","allowLocal":true})
  7. { "shardAdded" : "shard0001", "ok" : 1 }

这里要注意的是,在addshard中,我们也可以添加副本集,这样能达到更高的稳定性。

<2>片已经集群了,但是mongos不知道该如何切分数据,也就是我们先前所说的片键,在mongodb中设置片键要做两步:

1)开启数据库分片功能,命令很简单 enablesharding(),这里我就开启test数据库。
2)指定集合中分片的片键,这里我就指定为test.montest.name字段。
  1. db.runCommand({"enablesharding":"test"})
  2. db.runCommand({"shardcollection":"test.montest", "key":{"name":1}})

5: 查看效果
好了,至此我们的分片操作全部结束,接下来我们通过mongos向mongodb插入1w记录,然后通过printShardingStatus命令
查看mongodb的数据分片情况。

  1. for(var i=0;i<10000;i++){
  2. db.montest.insert({"name":"yjc"+i, "age":i});
  3. }
  4. mongos> db.montest.count()
  5. 10000
  6. mongos> db.printShardingStatus()
  7. --- Sharding Status ---
  8. sharding version: {
  9. "_id" : 1,
  10. "minCompatibleVersion" : 5,
  11. "currentVersion" : 6,
  12. "clusterId" : ObjectId("559745db7ba8ba85959c9bfb")
  13. }
  14. shards:
  15. { "_id" : "shard0000", "host" : "127.0.0.1:4444" }
  16. { "_id" : "shard0001", "host" : "127.0.0.1:5555" }
  17. balancer:
  18. Currently enabled: yes
  19. Currently running: no
  20. Failed balancer rounds in last 5 attempts: 0
  21. Migration Results for the last 24 hours:
  22. 1 : Success
  23. databases:
  24. { "_id" : "admin", "partitioned" : false, "primary" : "config" }
  25. { "_id" : "test", "partitioned" : true, "primary" : "shard0000" }
  26. test.montest
  27. shard key: { "name" : 1 }
  28. chunks:
  29. shard0000 2
  30. shard0001 1
  31. { "name" : { "$minKey" : 1 } } -->> { "name" : "yjc1" } on : shard0001 Timestamp(2, 0)
  32. { "name" : "yjc1" } -->> { "name" : "yjc6" } on : shard0000 Timestamp(2, 1)
  33. { "name" : "yjc6" } -->> { "name" : { "$maxKey" : 1 } } on : shard0000 Timestamp(1, 3)

这里主要看三点信息:
1)shards:我们清楚的看到已经别分为两个片了,shard0000和shard0001。
2)databases: 这里有个partitioned字段表示是否分区,这里清楚的看到test已经分区。
3)chunks:这个很有意思,我们发现集合被砍成四段:
无穷小 —— yjc , yjc1 —— yjc6, yjc6 —— 无穷大。
分区情况为:2:1,从后面的 on shardXXXX也能看得出。

后记:
问题:
1、在现有的数据库上做分片,怎么做?
2、一个分片Mongod进程挂掉了,是不是整个集合的查询就没有意义了啊?
发现只要有一个分片挂了,就查询不了数据了。

参考:
8天学通MongoDB——第六天 分片技术 - 一线码农 - 博客园
http://www.cnblogs.com/huangxincheng/archive/2012/03/07/2383284.html

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注