MongoDB提供了Replica pairs模式启动数据库,以这种方式启动后,数据库会自动协商谁是master谁是slave。一旦一个数据库服务器断电,另外一个会自动接管,并从那一刻起为master,万一另一个将来也出错了,那么master状态会转回第一个服务器。
(10.7.3.95 -> 10.7.3.97 单Replication 没有shard)
Replication-Sets
Step 1. 两台服务器单独启动mongod 并加上replSet = XXX 的选项。
Step 2. 随便选择一台服务器,进行Replication的配置.
var cfg = {_id:"dzhRepl", members:[
{_id:0, host:"10.7.3.95:10000"},
{_id:1, host:"10.7.3.97:10000"}
]}
rs.initiate(cfg)
到此就初始化好了,然后数据会慢慢迁移到Secondary.
1. rs.slaveOk() 使SECONDARY 也能查询到数据。
2. rs.stepDown() 使Primary降为Secondary
Master-Slave:
官方介绍: http://www.mongodb.org/display/DOCS/Master+Slave
需要注意参数:
Master configfile:
---
bind_ip = 10.7.3.95
port = 10000
fork = true
master = true
logappend = true
journal = true
dbpath = ../data/
logpath = ../log/mongodb.log
directoryperdb = true
Slave configfile:
----
bind_ip = 10.7.3.97
port = 10000
fork = true
logappend = true
slave = true # 启动slave
only = testDB # 只同步testDB数据库
source = 10.7.3.95:10000 # Master host和port
autoresync = true # 当发生意外时,会自动执行同步操作
slavedelay = 10 # 设定更新频率(s)
journal = true
dbpath = ../Slave
logpath = ../log/mongodb.log.
directoryperdb = true.
Master和Slave启动后,Master会首先首先创建local数据库,然后里面有oplog.$main 和slaves 和 system.indexes 和 system.users 等collection。
AutoSharding + Replication-Sets
MongoDB包括一个自动分片模块”mongos“ 从而可以构建一个大的水平可扩展的数据库集群,可以动态的添加服务器,自动建立一个水平扩展的数据库集群系统,将数据库分表存储在sharding的各个节点上
这里我使用3台服务器做测试。
分别为
10.X.X.21.163
10.X.X.21.164
10.X.X.228
................. (如果有服务没起来 ,根据经验可能是你Data下的文件锁问题,或者是命名不对)
准备工作:
每台机器先创建数据目录
Server 1
^_^[root@:/usr/local/mongodb]#mkdir -p data/shard11
^_^[root@:/usr/local/mongodb]#mkdir -p data/shard21
Server 2
^_^[root@:/usr/local/mongodb]#mkdir -p data/shard12
^_^[root@:/usr/local/mongodb]#mkdir -p data/shard22
Server 3
^_^[root@:/usr/local/mongodb]#mkdir -p data/shard13
^_^[root@:/usr/local/mongodb]#mkdir -p data/shard23
然后针对每个服务器进行Shard1 Replica Sets:
Server1:
./mongod --shardsvr --replSet shard1 --port 27017 --dbpath ../data/shard11 --oplogSize 100 --logpath ../data/shard11.log --logappend --fork.
./mongod --shardsvr --replSet shard1 --port 27017 --dbpath ../data/shard12 --oplogSize 100 --logpath ../data/shard12.log --logappend --fork.
Server3:
./mongod --shardsvr --replSet shard1 --port 27017 --dbpath ../data/shard13 --oplogSize 100 --logpath ../data/shard13.log --logappend --fork.
初始化Replica set:
> config={_id:'shard1',members:[
... {_id:0,host:'10.X.X.228:27017'},
... {_id:1,host:'10.X.X.163:27017'},
... {_id:2,host:'10.X.X.164:27017'}]
... }
rs.initiate(config);
Server1:
./mongod --shardsvr --replSet shard2 --port 27018 --dbpath ../data/shard21 --oplogSize 100 --logpath ../data/shard21.log --logappend --fork.
./mongod --shardsvr --replSet shard2 --port 27018 --dbpath ../data/shard22 --oplogSize 100 --logpath ../data/shard22.log --logappend --fork.
Server3:
./mongod --shardsvr --replSet shard2 --port 27018 --dbpath ../data/shard23 --oplogSize 100 --logpath ../data/shard23.log --logappend --fork.
经过第一次初始化后运行客户端会出现:
如果要用27018的 需要指定
./mongo 10.X.X.228:27018
再次初始化Replica set:
> config={_id:'shard1',members:[
... {_id:0,host:'10.X.X.228:27018'},
... {_id:1,host:'10.X.X.163:27018'},
... {_id:2,host:'10.X.X.164:27018'}]
... }
rs.initiate(config);
现在有2 个 Replica sets 和2个shards
.......................
再配置三台Config Server
mkdir -p data/config
./mongod --configsvr --dbpath ../data/config --port 20000 --logpath ../data/config.log -- logappend --fork.
每台Server都这样运行一遍(哎。好多配置啊。。。。。)
再配置Mongos(同样每台机器都要运行一遍)
./mongos --configdb 10.X.X.228:20000,10.X.X.163:20000,10.X.X.164:20000 --port 30000 - -chunkSize 5 --logpath ../data/mongos.log --logappend --fork
再Config Shard Cluster
连接到mongos,并且切换到admin
./mongo 10.X.X.228:30000/admin
>db
admin
再加入Shards
db.runCommand({addshard:"shard1/10.7.3.228:27017,10.10.21.163:27017,10.10.21.164:27017",name:"s1",maxsize:20480});
db.runCommand({addshard:"shard2/10.7.3.228:27018,10.10.21.163:27018,10.10.21.164:27018",name:"s2",maxsize:20480});
enable一个数据库
db.runCommand({ enablesharding:"test" })
数据集分片
db.runCommand({ shardcollection: "test.users", key: { _id:1 }})
> db.runCommand({listshards:1})
查看Sharding信息
printShardingStatus ()
查看Shard存储信息(需要先use test)
db.users.stats()
> use test
switched to db test
> db.users.stats()
{
"sharded" : true,
"ns" : "test.users",
"count" : 0,
"size" : 0,
"avgObjSize" : NaN,
"storageSize" : 8192,
"nindexes" : 1,
"nchunks" : 1,
"shards" : {
"s1" : {
"ns" : "test.users",
"count" : 0,
"size" : 0,
"storageSize" : 8192,
"numExtents" : 1,
"nindexes" : 1,
"lastExtentSize" : 8192,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 8192,
"indexSizes" : {
"_id_" : 8192
},
"ok" : 1
}
},
"ok" : 1
}
下面对分片进行测试:
#include <iostream>
#include <mongo/client/dbclient.h>
using namespace std;
using namespace mongo;
#define INIT_TIME \
struct timeval time1,time2; \
#define START_TIME \
gettimeofday(&time1,NULL); \
#define STOP_TIME \
gettimeofday(&time2,NULL); \
#define PRINT_TIME \
cout<<"Time:"<<time2.tv_sec-time1.tv_sec<<":"<<time2.tv_usec-time1.tv_usec<<endl;
int main() {
srand(time(NULL));
char ar[26+1];
DBClientConnection conn;
conn.connect("10.7.3.228:30000");
cout<<"MongoDB Connected OK!"<<endl;
int count=10000000;
INIT_TIME;
START_TIME;
//insert
#if 1
while (count--) { //loop insert 1000W
for (int i=0; i<26; i++) {
ar[i] = rand()%26+97;
}
ar[26]='\0';
BSONObj p = BSON("NewsId"<<ar);
conn.insert("test.users",p);
}
#endif
//Query
#if 0
cout<<"Count:"<<conn.count("News.News_key")<<endl;
BSONObj emptyObj;
auto_ptr<DBClientCursor> cursor = conn.query("News.News_key",emptyObj);
while (cursor->more()) {
BSONObj p = cursor->next();
cout<<p.getStringField("NewsId")<<endl;
if (p.getStringField("NewsId")=="bfatckiyxlougsxrffsnylsfuo"){
cout<<"find"<<endl;
break;
}
}
#endif
STOP_TIME;
PRINT_TIME;
return 0;
}
原文链接: http://blog.csdn.net/crazyjixiang/article/details/6623418