分片
在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求。
当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。
为什么使用分片
- 复制所有的写入操作到主节点
 
- 延迟的敏感数据会在主节点查询
 
- 单个副本集限制在12个节点
 
- 当请求量巨大时会出现内存不足。
 
- 本地磁盘不足
 
- 垂直扩展价格昂贵
 
分片组件

Sharded Cluster(分片集群)共有3个组件:
- shard(也可以配置成副本集,确保高可用)
 
- query router(查询路由器)
 
- config sever(配置服务器,一般会配置成副本集,确保高可用;以前的版本采取的方式使用3台独立的mongod实例)
 
config server保存了数据的分布情况,哪些数据在哪一个分片中,而query router提供了用户接口对分片进行操作。

分片实战
注意:分片是以集合为目标的
本机部署测试
- 配置服务器:是一个副本集,由3台mongod实例构成
 
- mongos路由:两台mongos实例
 
- shard节点:两个shard构成,每个shard都是一个副本集(包含了3个mongod实例)
 
11台机器。
启动
配置服务器
- 不能拥有arbiter
 
- 不能拥有delayed member
 
- 必须能够build indexes(buildIndexes属性不能为false)
 
先准备目录:
1 2 3 4 5 6 7 8 9 10 11 12
   | ➜  mongodb tree sharding  sharding └── config_server     ├── config1     │   ├── data     │   └── log     ├── config2     │   ├── data     │   └── log     └── config3         ├── data         └── log
   | 
 
启动配置服务器
1 2 3 4 5 6 7
   | mongod --configsvr --replSet mytest --port 28010 --dbpath sharding/config_server/config1/data --logpath sharding/config_server/config1/log/log.log --logappend --fork mongod --configsvr --replSet mytest --port 28011 --dbpath sharding/config_server/config2/data --logpath sharding/config_server/config2/log/log.log --logappend --fork mongod --configsvr --replSet mytest --port 28012 --dbpath sharding/config_server/config3/data --logpath sharding/config_server/config3/log/log.log --logappend --fork ➜  mongodb mongo localhost:28010 > myconfig = {_id:'mytest', configsvr:true, members:[{_id:0,host:'localhost:28010'},{_id:1,host:'localhost:28011'},{_id:2,host:'localhost:28012'}]}; > rs.initiate(myconfig); > rs.status();
   | 
 
启动查询路由器
1 2
   | mongos --configdb mytest/localhost:28010,localhost:28011,localhost:28012 --port 29010 mongos --configdb mytest/localhost:28010,localhost:28011,localhost:28012 --port 29011
   | 
 
分片副本集
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | ── shard1 │   ├── mongod1 │   │   └── data │   ├── mongod2 │   │   └── data │   └── mongod3 │       └── data └── shard2     ├── mongod4     │   └── data     ├── mongod5     │   └── data     └── mongod6         └── data
   | 
 
启动:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   | mongod --replSet shard1 --port 40001 --dbpath sharding/shard1/mongod1/data mongod --replSet shard1 --port 40002 --dbpath sharding/shard1/mongod2/data mongod --replSet shard1 --port 40003 --dbpath sharding/shard1/mongod3/data mongod --replSet shard2 --port 50001 --dbpath sharding/shard2/mongod4/data mongod --replSet shard2 --port 50002 --dbpath sharding/shard2/mongod5/data mongod --replSet shard2 --port 50003 --dbpath sharding/shard2/mongod6/data
  mongo localhost:40001
  > myconfig = {_id:'shard1', members:[{_id:0,host:'localhost:40001'},{_id:1,host:'localhost:40002'},{_id:2,host:'localhost:40003'}]}; > rs.initiate(myconfig);
  mongo localhost:50001
  > myconfig = {_id:'shard2', members:[{_id:0,host:'localhost:50001'},{_id:1,host:'localhost:50002'},{_id:2,host:'localhost:50003'}]}; > rs.initiate(myconfig);
   | 
 
配置分片
添加分片的时候,只写副本集其中一个mongod实例,它也能自动找到剩余的
1 2 3
   | mongo localhost:29010 mongos> sh.addShard('shard1/localhost:40001,localhost:40002,localhost:40003'); mongos> sh.addShard('shard2/localhost:50001'); 
   | 
 
下面开始设置分片,先设置可以分片的数据库,然后设置要分片的集合,需要设置索引字段,索引方式为hashed,注意要先切换到admin数据库。
1 2 3
   | mongos> use admin; mongos> sh.enableSharding('mytest'); mongos> sh.shardCollection('mytest.student',{_id:'hashed'});
   | 
 
接下来添加一些数据,然后可以看到分片的数据分片状态,我们也可以单独连接到某一个shard的副本集查看数据分布情况。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
   | mongos> for(var i = 0;i < 100;++i){db.student.insert({username:'hello' + i})}; mongos> db.printShardingStatus(); --- Sharding Status ---    sharding version: {   	"_id" : 1,   	"minCompatibleVersion" : 5,   	"currentVersion" : 6,   	"clusterId" : ObjectId("5a60594bd9fbe1b3ebca714e")   }   shards:         {  "_id" : "shard1",  "host" : "shard1/localhost:40001,localhost:40002,localhost:40003",  "state" : 1 }         {  "_id" : "shard2",  "host" : "shard2/localhost:50001,localhost:50002,localhost:50003",  "state" : 1 }   active mongoses:         "3.6.1" : 2   autosplit:         Currently enabled: yes   balancer:         Currently enabled:  yes         Currently running:  no         Failed balancer rounds in last 5 attempts:  0         Migration Results for the last 24 hours:                  No recent migrations   databases:         {  "_id" : "config",  "primary" : "config",  "partitioned" : true }                 config.system.sessions                         shard key: { "_id" : 1 }                         unique: false                         balancing: true                         chunks:                                 shard1	1                         { "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : shard1 Timestamp(1, 0)          {  "_id" : "mytest",  "primary" : "shard1",  "partitioned" : true }                 mytest.student                         shard key: { "_id" : "hashed" }                         unique: false                         balancing: true                         chunks:                                 shard1	2                         { "_id" : { "$minKey" : 1 } } -->> { "_id" : NumberLong(0) } on : shard1 Timestamp(1, 0)                          { "_id" : NumberLong(0) } -->> { "_id" : { "$maxKey" : 1 } } on : shard1 Timestamp(1, 1)          {  "_id" : "test",  "primary" : "shard1",  "partitioned" : false }
  |