@52fhy
        
        2015-09-20T07:50:21.000000Z
        字数 3322
        阅读 547
    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端口。
D:\Projects\mongodb\bin>mongod --dbpath=D:\Projects\mongodb\db --port 2222
2: 开启mongos服务器 
    这里要注意的是我们开启的是mongos,不是mongod,同时指定下config服务器,这里我就开启D盘上的mongodb,端口3333。
D:\Projects\mongodb2\bin>mongos --port 3333 --configdb=127.0.0.1:2222
3:启动mongod服务器 
     对分片来说,也就是要添加片了,这里开启E,F盘的mongodb,端口为:4444,5555。
mongod --dbpath=D:\Projects\mongodb3\db --port 4444mongod --dbpath=D:\Projects\mongodb4\db --port 55552015-07-04T10:34:15.394+0800 I NETWORK [initandlisten] waiting for connections on port 44442015-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()。
D:\Projects\mongodb\bin>mongo 127.0.0.1:3333/adminconnecting to: 127.0.0.1:3333/adminmongos>mongos> db.runCommand({"addshard":"127.0.0.1:4444","allowLocal":true}){ "shardAdded" : "shard0000", "ok" : 1 }mongos> db.runCommand({"addshard":"127.0.0.1:5555","allowLocal":true}){ "shardAdded" : "shard0001", "ok" : 1 }
这里要注意的是,在addshard中,我们也可以添加副本集,这样能达到更高的稳定性。
<2>片已经集群了,但是mongos不知道该如何切分数据,也就是我们先前所说的片键,在mongodb中设置片键要做两步:
1)开启数据库分片功能,命令很简单 enablesharding(),这里我就开启test数据库。
2)指定集合中分片的片键,这里我就指定为test.montest.name字段。
db.runCommand({"enablesharding":"test"})db.runCommand({"shardcollection":"test.montest", "key":{"name":1}})
5: 查看效果 
好了,至此我们的分片操作全部结束,接下来我们通过mongos向mongodb插入1w记录,然后通过printShardingStatus命令 
查看mongodb的数据分片情况。
for(var i=0;i<10000;i++){db.montest.insert({"name":"yjc"+i, "age":i});}mongos> db.montest.count()10000mongos> db.printShardingStatus()--- Sharding Status ---sharding version: {"_id" : 1,"minCompatibleVersion" : 5,"currentVersion" : 6,"clusterId" : ObjectId("559745db7ba8ba85959c9bfb")}shards:{ "_id" : "shard0000", "host" : "127.0.0.1:4444" }{ "_id" : "shard0001", "host" : "127.0.0.1:5555" }balancer:Currently enabled: yesCurrently running: noFailed balancer rounds in last 5 attempts: 0Migration Results for the last 24 hours:1 : Successdatabases:{ "_id" : "admin", "partitioned" : false, "primary" : "config" }{ "_id" : "test", "partitioned" : true, "primary" : "shard0000" }test.montestshard key: { "name" : 1 }chunks:shard0000 2shard0001 1{ "name" : { "$minKey" : 1 } } -->> { "name" : "yjc1" } on : shard0001 Timestamp(2, 0){ "name" : "yjc1" } -->> { "name" : "yjc6" } on : shard0000 Timestamp(2, 1){ "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