mongodb不推荐主从复制,推荐建立副本集(Replica Set)来保证1个服务挂了,可以有其他服务顶上,程序正常运行,几个服务的数据都是一样的,后台自动同步
【要搭建一个稳定的mongodb工程,副本集是必须的,因为他可以当你的主服务器挂掉后,根据选举机制自动选举出1个最适合的从服务器来做主服务器继续运行】
参考http://snoopyxdy.blog.163.com/blog/static/60117440201241694254441/
Replica Set使用的是n个mongod节点,构建具备自动的容错功能(auto-failover),自动恢复的(auto-recovery)的高可用方案。
使用Replica Set来实现读写分离。通过在连接时指定或者在主库指定slaveOk,由Secondary来分担读的压力,Primary只承担写操作。
对于Replica Set中的secondary 节点默认是不可读的。
--------------------------------------------------------
创建4个,3个MONGODB服务器,1个仲裁服务器
步骤1【创建数据存放目录】
分别创建4个节点分配数据存放的位置空间
$ mkdir -p /scmgt/data/r0
$ mkdir -p /scmgt/data/r1
$ mkdir -p /scmgt/data/r2
$ mkdir -p /scmgt/data/r3
步骤2【开启3个mondodb服务】
后台开启3个服务,查看端口是否暂用命令netstat -apn|grep 1000
/scmgt/mongodb/mongodb/bin/mongod --replSet gtSet --dbpath=/scmgt/data/r0 --logpath=/scmgt/mongodb/ro_log --logappend --port=9933 --fork
/scmgt/mongodb/mongodb/bin/mongod --replSet gtSet --rest --dbpath=/scmgt/data/r1 --logpath=/scmgt/mongodb/r1_log --logappend --port=9934 --fork
/scmgt/mongodb/mongodb/bin/mongod --replSet gtSet --dbpath=/scmgt/data/r2 --logpath=/scmgt/mongodb/r2_log --logappend --port=9935 --fork
/scmgt/mongodb/mongodb/bin/mongod --replSet gtSet --dbpath=/scmgt/data/r3 --logpath=/scmgt/mongodb/r3_log --logappend --port=9936 --fork
【-replSet gtSet:表示副本集的名字为“wzh”,这里的名字可以任意取;】
【--rest:是打开web监控页面,比如我们这里监听10001端口,则打开http://10.1.49.225:9934/就可以看到这个mongodb数据库进程的信息】
【启动不起来,如果出现 child process failed, exited with error number 100报错,请删除data下面的mongod.lock】
【查看logpath日志,提示replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG),这是因为我们还没有初始化这个set.没有执行第三步】
步骤3【初始化SET】
登陆mongodb后台:
cd /scmgt/mongodb/mongodb/bin
./mongo --port 9933
把下面config写入控制台
config = {_id: 'gtSet', members: [
{_id: 0, host: 'localhost:9933'},
{_id: 1, host: 'localhost:9934'},
{_id: 2, host: 'localhost:9935'},
{_id: 3, host: 'localhost:9936',arbiterOnly:true}]
}
然后执行rs.initiate(config);
【arbiterOnly(false):如果是true,则表示这个成员为仲裁节点,不接收数据;】
【priority(1.0):权重,更高的权重会被选举为主节点】
查看日志,如果出现
rs.initiate(config); rs.initiate(config);
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}表示将在1分钟后初始化完毕
之后执行 rs.status(),查看详细
【这里有个值"myState",如果这个值为1,说明是主控节点(master);如果是 2 ,说明是从属节点(slave).】
----------------------搭建完毕,添加数据,来需要验证的--------------------
1:主从服务器数据是否同步,从服务器没有读写权限
a:向主服务器写入数据 ok 后台自动同步到从服务器,从服务器有数据
b:向从服务器写入数据 false 从服务器不能写
c:主服务器读取数据 ok
d:从服务器读取数据 false 从服务器不能读
2:关闭主服务器,从服务器是否能顶替
kill -2 9933的pid
mongo的命令行执行rs.status() 发现PRIMARY替换了主机了
3:关闭的服务器,再恢复,以及主从切换
a:直接启动关闭的服务,rs.status()中会发现,原来挂掉的主服务器重启后变成从服务器了
b:额外删除新的服务器 rs.remove("localhost:9933"); rs.status()
c:额外增加新的服务器 rs.add({_id:0,host:"localhost:9933",priority:1});
d:让新增的成为主服务器 rs.stepDown(),注意之前的 priority投票
4:从服务器读写
db.getMongo().setSlaveOk();
db.getMongo().slaveOk();//从库只读,没有写权限,这个方法java里面不推荐了
db.setReadPreference(ReadPreference.secondaryPreferred());//在复制集中优先读secondary,如果secondary访问不了的时候就从master中读
db.setReadPreference(ReadPreference.secondary());//只从secondary中读,如果secondary访问不了的时候就不能进行查询
-------------------------------------------------------------------
日志查看
MongoDB的Replica Set 架构是通过一个日志来存储写操作的,这个日志就叫做”oplog”,它存在于”local”数据库中,oplog的大小是可以通过mongod的参数”—oplogSize”来改变oplog的日志大小。
use local
switched to db local
db.oplog.rs.find()
{ "ts" : { "t" : 1342511269000, "i" : 1 }, "h" : NumberLong(0), "op" : "n", "ns" : "", "o" : { "msg" : "initiating set" } }
字段说明:
ts: 某个操作的时间戳
op: 操作类型,如下:
i: insert
d: delete
u: update
ns: 命名空间,也就是操作的collection name
o: document的内容