mongodb的auto-sharding功能是指mongodb通过mongos自动建立一个水平扩展的数据库集群系统,将数据库分表存储在sharding的各个节点上。通过把Sharding和Replica Sets相结合,可以搭建一个分布式的,高可用性,自动水平扩展的集群。
构建MongoDB Sharding Cluster,需要三种角色:
Shard Server:
mongod 实例, 使用 Replica Sets,确保每个数据节点都具有备份、自动容错转移、自动恢复能力。用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个relica set承担,防止主机单点故障
Config Server:
mongod 实例,使用 3 个配置服务器,确保元数据完整性(two-phase commit)。存储了整个 Cluster Metadata,其中包括 chunk 信息。
Route Server:
mongos 实例,配合 LVS,实现负载平衡,提高接入性能(high performance)。前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。
下面尝试构建一个mongodb sharding cluster,包含两个shard server,3个config server,一个route server,每个分片节点都部署成副本集。
1、架构说明:
shard1: 172.16.171.155 (a replica set on ports 27017,27018,27019)
shard2: 172.16.171.156 (a replica set on ports 27017,27018,27019)
mongos and 3 config servers: 172.16.171.160(mongos server at port 27020 and 3 config servers on ports 27017,27018,27019)
2、创建过程
1)为shard1和shard2分别创建复制集(这里以shard1为例,shard2按照shard1方法即可)
mkdir -p ~/data/{rs1,rs2,rs3} #3个文件夹分别保存3个mongod实例的数据
mongod --replSet shard1 --dbpath ~/data/rs1 --logpath ~/data/rs1/mongod.log --fork --port 27017
mongod --replSet shard1 --dbpath ~/data/rs2 --logpath ~/data/rs2/mongod.log --fork --port 27018
mongod --replSet shard1 --dbpath ~/data/rs3 --logpath ~/data/rs3/mongod.log --fork --port 27019
MongoDB Enterprise > cfg={
... _id:'shard1',
... members:[
... {_id:0,host:'172.16.171.155:27017'},
... {_id:1,host:'172.16.171.155:27018'},
... {_id:2,host:'172.16.171.155:27019',arbiterOnly:true}]}
{
"_id" : "shard1",
"members" : [
{
"_id" : 0,
"host" : "172.16.171.155:27017"
},
{
"_id" : 1,
"host" : "172.16.171.155:27018"
},
{
"_id" : 2,
"host" : "172.16.171.155:27019",
"arbiterOnly" : true
}
]
}
MongoDB Enterprise > rs.initiate(cfg)
{ "ok" : 1 }
MongoDB Enterprise shard1:OTHER>
MongoDB Enterprise shard1:SECONDARY> rs.status()
{
"set" : "shard1",
"date" : ISODate("2016-10-12T05:50:05.592Z"),
"myState" : 1,
"term" : NumberLong(1),
"heartbeatIntervalMillis" : NumberLong(2000),
"members" : [
{
"_id" : 0,
"name" : "172.16.171.155:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 604,
"optime" : {
"ts" : Timestamp(1476251384, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2016-10-12T05:49:44Z"),
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1476251383, 1),
"electionDate" : ISODate("2016-10-12T05:49:43Z"),
"configVersion" : 1,
"self" : true
},
{
"_id" : 1,
"name" : "172.16.171.155:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 32,
"optime" : {
"ts" : Timestamp(1476251384, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2016-10-12T05:49:44Z"),
"lastHeartbeat" : ISODate("2016-10-12T05:50:05.424Z"),
"lastHeartbeatRecv" : ISODate("2016-10-12T05:50:05.132Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "172.16.171.155:27017",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "172.16.171.155:27019",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 32,
"lastHeartbeat" : ISODate("2016-10-12T05:50:05.424Z"),
"lastHeartbeatRecv" : ISODate("2016-10-12T05:50:05.126Z"),
"pingMs" : NumberLong(0),
"configVersion" : 1
}
],
"ok" : 1
}
MongoDB Enterprise shard1:PRIMARY>
2)launch config servers
mongod --dbpath ~/data/cfg1 --logpath ~/data/cfg1/mongod.log --port 27017 --fork --configsvr
mongod --dbpath ~/data/cfg2 --logpath ~/data/cfg2/mongod.log --port 27018 --fork --configsvr
mongod --dbpath ~/data/cfg3 --logpath ~/data/cfg3/mongod.log --port 27019 --fork --configsvr
3)launch mongos server
mongos --logpath ~/data/mongos1/mongos.log --port 27020 --fork --configdb 172.16.171.160:27017,172.16.171.160:27018,172.16.171.160:27019
4)连接到mongos添加分片
mongo --port 27020
MongoDB Enterprise mongos> sh.addShard('shard1/172.16.171.155:27017')
{ "shardAdded" : "shard1", "ok" : 1 }
MongoDB Enterprise mongos> sh.addShard('shard2/172.16.171.156:27017')
{ "shardAdded" : "shard2", "ok" : 1 }
5)enble sharding and sharding collection
MongoDB Enterprise mongos> sh.enableSharding('test')
{ "ok" : 1 }
sh.shardCollection('test.testcol',{a:1,b:1})#{a:1,b:1}片键
{ "collectionsharded" : "test.testcol", "ok" : 1 }
查看分片信息:
MongoDB Enterprise mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("57fdd3544cfff1cd9c6ffeeb")
}
shards:
{ "_id" : "shard1", "host" : "shard1/172.16.171.155:27017,172.16.171.155:27018" }
{ "_id" : "shard2", "host" : "shard2/172.16.171.156:27017,172.16.171.156:27018,172.16.171.156:27019" }
active mongoses:
"3.2.9" : 1
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" : "test", "primary" : "shard1", "partitioned" : true }
test.testcol
shard key: { "a" : 1, "b" : 1 }
unique: false
balancing: true
chunks:
shard1 1
{ "a" : { "$minKey" : 1 }, "b" : { "$minKey" : 1 } } -->> { "a" : { "$maxKey" : 1 }, "b" : { "$maxKey" : 1 } } on : shard1 Timestamp(1, 0)
MongoDB Enterprise mongos>
5)插入大量的数据测试
插入js代码如下:
MongoDB Enterprise mongos> for (i=0;i<10000;i++){
... arr=[];
... for(j=0;j<1000;j++){
... arr.push(
... {
... a:i,
... b:j,
... c:'sharding test'
... })
... };
... db.testcol.insert(arr);
... };
6)查分片的信息
MongoDB Enterprise mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("57fdd3544cfff1cd9c6ffeeb")
}
shards:
{ "_id" : "shard1", "host" : "shard1/172.16.171.155:27017,172.16.171.155:27018" }
{ "_id" : "shard2", "host" : "shard2/172.16.171.156:27017,172.16.171.156:27018,172.16.171.156:27019" }
active mongoses:
"3.2.9" : 1
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
19 : Success
databases:
{ "_id" : "test", "primary" : "shard1", "partitioned" : true }
test.testcol
shard key: { "a" : 1, "b" : 1 }
unique: false
balancing: true
chunks:
shard1 19
shard2 19
too many chunks to print, use verbose if you want to force print
MongoDB Enterprise mongos>