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>