一、概述要构建一个MongoDBShardingCluster,需要三种角色:ShardServer即存储实际数据的分片,每个Shard可以是一个mongod实例,也可以是一组mongod实例构成的ReplicaSet。为了实现每个Shard内部的auto-failover,MongoDB官方建议每个Shard为一组R
一、概述
要构建一个 MongoDB Sharding Cluster,需要三种角色:
Shard Server
即存储实际数据的分片,每个Shard可以是一个mongod实例,也可以是一组mongod实例构成的Replica
Set。为了实现每个Shard内部的auto-failover,MongoDB官方建议每个Shard
为一组Replica Set。
Config Server
为了将一个特定的collection存储在多个shard中,需要为该collection指定一个shard
key,例如{age: 1} ,shard key可以决定该条记录属于哪个chunk。Config
Servers就是用来存储:所有shard节点的配置信息、每个chunk的shard
key范围、chunk在各shard的分布情况、该集群中所有DB和collection的sharding配置信息。
Route Process
这是一个前端路由,客户端由此接入,然后询问Config
Servers需要到哪个Shard上查询或保存记录,再连接相应的Shard进行操作,最后将结果返回给客户端。客户端只需要将原本发给mongod的查询或更新请求原封不动地发给Routing
Process,而不必关心所操作的记录存储在哪个Shard上。
二、Sharding配置
192.168.4.93
192.168.4.94
192.168.4.89
在3台机器上面做主从配置,首先需要在3台机器上面的,相同路径下已经安装好
mongodb(安装在/usr/local/
mongodb/bin/mongod),并且在单机模式下可以正常启动。参考 MongoDB单机安装和使用 。
为了避免不必要的错误,保证3台机器之间能够互相访问,端口不受限制,如果是本地测试机,最好是关掉防火墙(service
iptables stop)。
完成上面的工作外,执行下面操作流程
1、94,89两台机器作为Shard
Server,在上面分别启动下面命令(先要创建/data/database/mongodb_s,以及/data/logs/日志文件夹):
/usr/local/mongodb/bin/mongod --shardsvr --fork
--dbpath=/data/database/mongodb_s
--logpath=/data/logs/mongodb_s.log --port=27200 --oplogSize 128
--logappend --journal
2、93机器作为Config Server和Route
Process(同样需要创建对应的数据库文件夹/data/database/mongodb_c)
启动Config Server
/usr/local/mongodb/bin/mongod --configsvr --fork
--dbpath=/data/database/mongodb_c
--logpath=/data/logs/mongodb_c.log --port=30001 --oplogSize 128
--logappend --journal
启动 Route Process,指定了Config
Server的ip和端口,注意这个智能是奇数。chunkSize这一项是用来指定chunk的大小的,单位是MB,默认大小
为200MB,为了方便测试Sharding效果,我们把chunkSize指定为 1MB
/usr/local/mongodb/bin/mongos --cOnfigdb=192.168.4.93:30001
--fork --logpath=/data/logs/mongodb_r.log --port=20001 --logappend
--chunkSize=1
3、配置Sharding
a、在93机器上面执行
/usr/local/mongodb/bin/mongo --port 20001
> use admin
switched to db admin
> db.adminCommand({addshard:"192.168.4.94:27200"}) 添加Shard
Server
{ "shardAdded" : "shard0000", "ok" : 1 }
> db.adminCommand({addshard:"192.168.4.89:27200"})
{ "shardAdded" : "shard0001", "ok" : 1 }
> db.adminCommand({enablesharding:"test"}) -设置分片存储的数据库
{ "ok" : 1 }
> db.adminCommand({shardcollection:"test.users",key:{_id:1}})
--设置分片的集合名称,且必须指定Shard Key,系统会自动创建索引
{ "collectionsharded" : "test.users", "ok" : 1 }
b、验证test库
查看users表的属性
db.users.stats()
{
"sharded" : true,
"ns" : "test.users",
"count" : 0,
"size" : 0,
"avgObjSize" : NaN,
"storageSize" : 47822848,
"nindexes" : 1,
"nchunks" : 1,
"shards" : {
"shard0000" : {
"ns" : "test.users",
"count" : 0,
"size" : 0,
"storageSize" : 47822848,
"numExtents" : 9,
"nindexes" : 1,
"lastExtentSize" : 14495232,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 8192,
"indexSizes" : {
"_id_" : 8192
},
"ok" : 1
}
},
"ok" : 1
}
插入数据,然后再查看状态,可以看到数据已经储存到2个shard
> db.users.stats()
{
"sharded" : true,
"ns" : "test.users",
"count" : 200000,
"size" : 19200000,
"avgObjSize" : 96,
"storageSize" : 69071104,
"nindexes" : 1,
"nchunks" : 18,
"shards" : {
"shard0000" : {
"ns" : "test.users",
"count" : 61997,
"size" : 5951712,
"avgObjSize" : 96,
"storageSize" : 47822848,
"numExtents" : 9,
"nindexes" : 1,
"lastExtentSize" : 14495232,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 2596864,
"indexSizes" : {
"_id_" : 2596864
},
"ok" : 1
},
"shard0001" : {
"ns" : "test.users",
"count" : 138003,
"size" : 13248288,
"avgObjSize" : 96,
"storageSize" : 21248256,
"numExtents" : 7,
"nindexes" : 1,
"lastExtentSize" : 10066176,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 5758976,
"indexSizes" : {
"_id_" : 5758976
},
"ok" : 1
}
},
"ok" : 1
}
>
c、现有表sharding
插入数据,
> db.users2.stats() 数据只保存一个shard上面
{
"ns" : "test.users2",
"sharded" : false,
"primary" : "shard0000",
"ns" : "test.users2",
"count" : 200000,
"size" : 19200000,
"avgObjSize" : 96,
"storageSize" : 53806336,
"numExtents" : 11,
"nindexes" : 1,
"lastExtentSize" : 13045504,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 8323072,
"indexSizes" : {
"_id_" : 8323072
},
"ok" : 1
}
>
db.adminCommand({shardcollection:"test.users2",key:{_id:1}})
对该集合做sharding
{ "collectionsharded" : "test.users2", "ok" : 1 }
> db.users2.stats() 查看数据已经储存到2个shard中
{
"sharded" : true,
"ns" : "test.users2",
"count" : 200000,
"size" : 19200000,
"avgObjSize" : 96,
"storageSize" : 54
502656,
"nindexes" : 1,
"nchunks" : 37,
"shards" : {
"shard0000" : {
"ns" : "test.users2",
"count" : 194539,
"size" : 18675744,
"avgObjSize" : 96,
"storageSize" : 53806336,
"numExtents" : 11,
"nindexes" : 1,
"lastExtentSize" : 13045504,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 8101888,
"indexSizes" : {
"_id_" : 8101888
},
"ok" : 1
},
"shard0001" : {
"ns" : "test.users2",
"count" : 5461,
"size" : 524256,
"avgObjSize" : 96,
"storageSize" : 696320,
"numExtents" : 4,
"nindexes" : 1,
"lastExtentSize" : 524288,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 237568,
"indexSizes" : {
"_id_" : 237568
},
"ok" : 1
}
},
"ok" : 1
}
>
d、添加移除 Shard Server
移除Server
> db.adminCommand({removeshard:"192.168.4.89:27200"})
{
"msg" : "draining started successfully",
"state" : "started",
"shard" : "shard0001",
"ok" : 1
}
> db.users2.stats()
{
"sharded" : true,
"ns" : "test.users2",
"count" : 200000,
"size" : 19200000,
"avgObjSize" : 96,
"storageSize" : 53806336,
"nindexes" : 1,
"nchunks" : 37,
"shards" : {
"shard0000" : {
"ns" : "test.users2",
"count" : 200000,
"size" : 19200000,
"avgObjSize" : 96,
"storageSize" : 53806336,
"numExtents" : 11,
"nindexes" : 1,
"lastExtentSize" : 13045504,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 11526144,
"indexSizes" : {
"_id_" : 11526144
},
"ok" : 1
}
},
"ok" : 1
}
添加Server
db.adminCommand({addshard:"192.168.4.89:27200"})
{
"ok" : 0,
"errmsg" : "can't add shard 192.168.4.89:27200 because a local
database 'test' exists in another shard0000:192.168.4.94:27200"
}
这个时候再添加,因为test已经存在了,去89那台上面执行
> use test
> db.dropDatabase()
{ "dropped" : "test", "ok" : 1 }
然后再添加
> db.adminCommand({addshard:"192.168.4.89:27200"})
{ "shardAdded" : "shard0001", "ok" : 1 }
查看users状态,已经重新分片了,下面的信息显示数据还在复制过程中,你看到shard0001位54619,等数据复制后应该是10000
> db.users2.stats()
{
"sharded" : true,
"ns" : "test.users2",
"count" : 200000,
"size" : 19200000,
"avgObjSize" : 96,
"storageSize" : 64988416,
"nindexes" : 1,
"nchunks" : 37,
"shards" : {
"shard0000" : {
"ns" : "test.users2",
"count" : 145381,
"size" : 13956576,
"avgObjSize" : 96,
"storageSize" : 53806336,
"numExtents" : 11,
"nindexes" : 1,
"lastExtentSize" : 13045504,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 7479296,
"indexSizes" : {
"_id_" : 7479296
},
"ok" : 1
},
"shard0001" : {
"ns" : "test.users2",
"count" : 54619,
"size" : 5243424,
"avgObjSize" : 96,
"storageSize" : 11182080,
"numExtents" : 6,
"nindexes" : 1,
"lastExtentSize" : 8388608,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 4055040,
"indexSizes" : {
"_id_" : 4055040
},
"ok" : 1
}
},
"ok" : 1
}
3、其他命令
> db.adminCommand({ listshards: 1 })列出全部的sharding服务器
{
"shards" : [
{
"_id" : "shard0000",
"host" : "192.168.4.94:27200"
},
{
"_id" : "shard0001",
"host" : "192.168.4.89:27200"
}
],
"ok" : 1
}
> db.adminCommand({ isdbgrid:1 }) 判断是否是sharding
{ "isdbgrid" : 1, "hostname" : "booksir.om", "ok" : 1 }
> printShardingStatus() 查看sharding信息
--- Sharding Status ---
sharding version: { "_id" : 1, "version" : 3 }
shards:
{ "_id" : "shard0000", "host" : "192.168.4.94:27200" }
{ "_id" : "shard0001", "host" : "192.168.4.89:27200" }
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config"
}
{ "_id" : "test", "partitioned" : true, "primary" : "shard0000"
}
test.users chunks:
shard0001 9
shard0000 9
{ "_id" : { $minKey : 1 } } -->> { "_id" :
ObjectId("50060bc893ba26048a6bbb17") } on : shard0001 { "t" :
21000, "i" : 0 }
{ "_id" : ObjectId("50060bc893ba26048a6bbb17") } -->> {
"_id" : ObjectId("50060bc993ba26048a6beac8") } on : shard0001 { "t"
: 22000, "i" : 0 }
{ "_id" : ObjectId("50060bc993ba26048a6beac8") } -->> {
"_id" : ObjectId("50060bcd93ba26048a6c19d9") } on : shard0001 { "t"
: 23000, "i" : 0 }
{ "_id" : ObjectId("50060bcd93ba26048a6c19d9") } -->> {
"_id" : ObjectId("50060bce93ba26048a6c4ae1") } on : shard0001 { "t"
: 24000, "i" : 0 }
{ "_id" : ObjectId("50060bce93ba26048a6c4ae1") } -->> {
"_id" : ObjectId("50060bce93ba26048a6c7621") } on : shard0001 { "t"
: 25000, "i" : 0 }
{ "_id" : ObjectId("50060bce93ba26048a6c7621") } -->> {
"_id" : ObjectId("50060bd393ba26048a6cad44") } on : shard0001 { "t"
: 26000, "i" : 0 }
{ "_id" : ObjectId("50060bd393ba26048a6cad44") } -->> {
"_id" : ObjectId("50060bd493ba26048a6cdb4c") } on : shard0001 { "t"
: 27000, "i" : 0 }
{ "_id" : ObjectId("50060bd493ba26048a6cdb4c") } -->> {
"_id" : ObjectId("50060bd793ba26048a6d0979") } on : shard0001 { "t"
: 28000, "i" : 0 }
{ "_id" : ObjectId("50060bd793ba26048a6d0979") } -->> {
"_id" : ObjectId("50060bd893ba26048a6d3aac") } on : shard0001 { "t"
: 29000, "i" : 0 }
{ "_id" : ObjectId("50060bd893ba26048a6d3aac") } -->> {
"_id" : ObjectId("50060bd993ba26048a6d6bb3") } on : shard0000 { "t"
: 29000, "i" : 1 }
{ "_id" : ObjectId("50060bd993ba26048a6d6bb3") } -->> {
"_id" : ObjectId("50060bda93ba26048a6d96c2") } on : shard0000 { "t"
: 13000, "i" : 0 }
{ "_id" : ObjectId("50060bda93ba26048a6d96c2") } -->> {
"_id" : ObjectId("50060bdb93ba26048a6dc560") } on : shard0000 { "t"
: 14000, "i" : 0 }
{ "_id" : ObjectId("50060bdb93ba26048a6dc560") } -->> {
"_id" : ObjectId("50060bdc93ba26048a6df4bb") } on : shard0000 { "t"
: 15000, "i" : 0 }
{ "_id" : ObjectId("50060bdc93ba26048a6df4bb") } -->> {
"_id" : ObjectId("50060bdd93ba26048a6e222d") } on : shard0000 { "t"
: 16000, "i" : 0 }
{ "_id" : ObjectId("50060bdd93ba26048a6e222d") } -->> {
"_id" : ObjectId("50060bde93ba26048a6e533e") } on : shard0000 { "t"
: 17000, "i" : 0 }
{ "_id" : ObjectId("50060bde93ba26048a6e533e") } -->> {
"_id" : ObjectId("50060bdf93ba26048a6e8230") } on : shard0000 { "t"
: 18000, "i" : 0 }
{ "_id" : ObjectId("50060bdf93ba26048a6e8230") } -->> {
"_id" : ObjectId("50060be093ba26048a6eb2e7") } on : shard0000 { "t"
: 19000, "i" : 0 }
{ "_id" : ObjectId("50060be093ba26048a6eb2e7") } -->> {
"_id" : { $maxKey : 1 } } on : shard0000 { "t" : 20000, "i" : 0
}
test.users2 chunks:
shard0001 18
shard0000 19
too many chunksn to print, use verbose if you want to force
print