前面我们介绍了mongodb的架构。下面我们就来实际搭建一个mongodb sharded cluster。
- 首先搭建我们的shard server,本例中是起了两个单实例的mongodb server,当然你也可以每个shard都部署为副本集模式。这里我们简单起见先都为单实例。
配置:
//mongo 1
logpath=D:\mongo\data\log\mongod.log
dbpath=D:\mongo\data\db
port=20170
logappend=true
shardsvr=true
// mongo 2
logpath=D:\mongo-1\data\log\mongod.log
dbpath=D:\mongo-1\data\db
port=20171
logappend=true
shardsvr=true
这里比较重要的就是shardsvr这个参数,表示以sharding模式启动Mongodb服务器。
然后运行mongod --config=configpath 启动这两个mongo server。
- 搭建config server,之前的文章中我们提到过从3.4 版本开始configserver必须部署为副本集。因此部署了三个config server节点。
配置如下:
logpath=D:\mongo-config\data\log\mongod.log
dbpath=D:\mongo-config\data\db
port=20000
logappend=true
profile=0
configsvr=true
replSet=shard_config
其他两个config server的配置类似,比较重要的是configsvr的值必须是true,表示为config server;replSet的值三个节点需保持一致,代表整个副本集的名称。启动完三个config server之后,通过mongo shell连接到其中一台server上,然后运行下面的命令:
//切换到admin数据库
use admin
//创建副本集
config_shard={_id : 'shard_config', members:[{_id:0, host:'127.0.0.1:20000'},{_id:1, host:'127.0.0.1:20001'},{_id:2,host:'127.0.0.1:20002'}]};
rs.initiate(config_shard)
执行完上面的命令之后,config server就完成了replica Set 的配置。
- 配置sharding
- 第一步我们要启动一个路由节点,配置如下:
logpath=D:\mongo-route\data\log\mongod.log
port=30000
logappend=true
maxConns=1000
configdb=shard_config/127.0.0.1:20000,127.0.0.1:20001,127.0.0.1:20002
其中configdb就是我们刚刚搭建的config server,为三节点副本集。
然后运行:mongos -f configpath启动路由节点。
- 第二步添加shard server
首先通过mongo shell连接到30000端口即路由节点,运行user admin切换的admin 数据库,然后运行下面的命令添加shard server以及指定shard的collection和shard key:
db.runCommand({addshard:"root:[email protected]:20170"});
db.runCommand({addshard:"root:[email protected]:20171"});
db.runCommand({enablesharding:'Gps'})//指定需要shard 的数据库
db.runCommand({shardcollection:'Gps.positions', key:{plateNo:1,gpsTime:1}})//指定需要shard的collection以及shard key。
查看sharding的状态:
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5b87bbcd0ed472efefd364f8")
}
shards:
{ "_id" : "shard_a", "host" : "127.0.0.1:20170", "state" : 1 }
{ "_id" : "shard_b", "host" : "127.0.0.1:20171", "state" : 1 }
active mongoses:
"3.4.16" : 1
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
NaN
Failed balancer rounds in last 5 attempts: 5
Last reported error: ����Ŀ�����������ܾ��������ӡ�
Time of Reported error: Thu Sep 06 2018 20:09:52 GMT+0800
Migration Results for the last 24 hours:
No recent migrations
databases:
{ "_id" : "", "primary" : "shard_a", "partitioned" : true }
{ "_id" : "Gps", "primary" : "shard_a", "partitioned" : true }
Gps.positions
shard key: { "plateNo" : 1, "gpsTime" : 1 }
unique: false
balancing: true
chunks:
shard_a 5
shard_b 4
{ "plateNo" : { "$minKey" : 1 }, "gpsTime" : { "$minKey" : 1 } } -->> { "plateNo" : "沪A12341", "gpsTime" : ISODate("2018-08-30T10:28:43.523Z") } on : shard_b Timestamp(2, 0)
{ "plateNo" : "沪A12341", "gpsTime" : ISODate("2018-08-30T10:28:43.523Z") } -->> {
"plateNo" : "沪A123413441",
"gpsTime" : ISODate("2018-08-30T10:51:14.020Z")
} on : shard_b Timestamp(3, 0)
{
"plateNo" : "沪A123413441",
"gpsTime" : ISODate("2018-08-30T10:51:14.020Z")
} -->> {
"plateNo" : "沪A123416886",
"gpsTime" : ISODate("2018-08-30T10:56:59.982Z")
} on : shard_b Timestamp(4, 0)
{
"plateNo" : "沪A123416886",
"gpsTime" : ISODate("2018-08-30T10:56:59.982Z")
} -->> { "plateNo" : "沪A12342628", "gpsTime" : ISODate("2018-08-30T10:33:07.646Z") } on : shard_b Timestamp(5, 0)
{ "plateNo" : "沪A12342628", "gpsTime" : ISODate("2018-08-30T10:33:07.646Z") } -->> { "plateNo" : "沪A12343424", "gpsTime" : ISODate("2018-08-30T10:34:27.616Z") } on : shard_a Timestamp(5, 1)
{ "plateNo" : "沪A12343424", "gpsTime" : ISODate("2018-08-30T10:34:27.616Z") } -->> { "plateNo" : "沪A12344272", "gpsTime" : ISODate("2018-08-30T10:35:52.819Z") } on : shard_a Timestamp(2, 7)
{ "plateNo" : "沪A12344272", "gpsTime" : ISODate("2018-08-30T10:35:52.819Z") } -->> { "plateNo" : "沪A12347743", "gpsTime" : ISODate("2018-08-30T10:41:41.412Z") } on : shard_a Timestamp(2, 3)
{ "plateNo" : "沪A12347743", "gpsTime" : ISODate("2018-08-30T10:41:41.412Z") } -->> { "plateNo" : "沪A1234876", "gpsTime" : ISODate("2018-08-30T10:30:11.567Z") } on : shard_a Timestamp(2, 4)
{ "plateNo" : "沪A1234876", "gpsTime" : ISODate("2018-08-30T10:30:11.567Z") } -->> { "plateNo" : { "$maxKey" : 1 }, "gpsTime" : { "$maxKey" : 1 } } on : shard_a Timestamp(1, 3)
- 测试
使用以下代码我们向db中插入了20000条数据
const mongoose = require("mongoose");
const co = require("co");
var Schema = mongoose.Schema;
var position = new Schema({
plateNo: String,
gpsTime: Date,
lat: String,
lon: String,
speed: String,
address: String
});
mongoose.connect('mongodb://gpsowner:[email protected]:30000/Gps',{ useNewUrlParser: true } );
var PositionModel = mongoose.model("Position", position);
describe("", function () {
it("", function (done) {
this.timeout(100000);
co(function* () {
for (var i = 0; i < 20000; i++) {
let gpsTime = new Date(new Date().getTime() + i * 100)
let position = new PositionModel({
plateNo: '沪A1234' + i,
gpsTime: gpsTime,
lat: "1232",
lon: '1234',
speed: '0',
address: 'zhongguo'
});
yield position.save();
}
}).then(done, done);
})
});
然后我们查看表的状态:
{
"raw" : {
"127.0.0.1:20170" : {
"db" : "Gps",
"collections" : 1,
"views" : 0,
"objects" : 8189,
"avgObjSize" : 136.88960801074612,
"dataSize" : 1120989,
"storageSize" : 356352,
"numExtents" : 0,
"indexes" : 2,
"indexSize" : 274432,
"ok" : 1
},
"127.0.0.1:20171" : {
"db" : "Gps",
"collections" : 1,
"views" : 0,
"objects" : 11811,
"avgObjSize" : 137.82922699178732,
"dataSize" : 1627901,
"storageSize" : 507904,
"numExtents" : 0,
"indexes" : 2,
"indexSize" : 372736,
"ok" : 1
}
},
"objects" : 20000,
"avgObjSize" : 136.59055,
"dataSize" : 2748890,
"storageSize" : 864256,
"numExtents" : 0,
"indexes" : 4,
"indexSize" : 647168,
"fileSize" : 0,
"extentFreeList" : {
"num" : 0,
"totalSize" : 0
},
"ok" : 1
}
可以看到一台server上存储了8189条数据,另外一台存储了11811条数据。到这里sharded cluster就搭建完成了。