一、原理

      通俗的讲就是用多台机器进行同一数据的异步同步,从而使多台机器拥有同一数据的多个副本,其中有一个主服务器(primary),用户处理客户端请求,还有多个备份服务器(secondary),用户保存主服务器的数据副本。并且当主库奔溃时在不需要用户干预的情况下自动切换其他备份服务器做主库。而且还可以利用副本服务器做只读服务器,实现读写分离,提高负载。

     mongodb的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。

     mongodb各个节点常见的搭配方式为:一主一从、一主多从。

     主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。


二、环境准备


[root@node1 bin]# cat /etc/redhat-release

CentOS release 6.6 (Final)


两台服务器:192.168.200.140(primary) 192.168.200.144(secondary)


三、复制集搭建过程


     1.启动节点

          (1)启动节点1

                    [root@node1 bin]# ./mongod --dbpath=/a01/mongodb/data/ --logpath=/a01/mongodb/logs/node1.log --oplogSize 400 --maxConns=2000 --replSet replcopy/192.168.200.140:27017 --fork


          (2)启动节点2

                    [root@node2 bin]# ./mongod --dbpath=/a01/mongodb/data/ --logpath=/a01/mongodb/logs/node2.log --oplogSize 400 --maxConns=2000 --replSet replcopy/192.168.200.144:27017 --fork

                   

          (3)启动arbiter节点

                     [root@node2 bin]#  ./mongod --dbpath=/a01/mongodb/arbiter/ --logpath=/a01/mongodb/logs/arbiter.log --port 20000 --replSet replcopy/192.168.200.140:27017,192.168.200.144:27017 --fork


     2.初始化节点

          (1)运行第一个节点的Mogo

               [root@node1 bin]# ./mongo

          (2)配置复制集

               > cfg = { _id: "replcopy", members:[ { _id:0,host:"192.168.200.140:27017"}, { _id:1, host:"192.168.200.144:27017"} ]}

          (3)初始化配置集

               > rs.initiate(cfg)


          3. 加入arbiter(仲裁)节点

          (1)replcopy:OTHER> rs.addArb("192.168.200.144:20000");

          (2)查看状态

               replcopy:PRIMARY> rs.status();


      4.复制测试

          (1)主节点中新建数据库并添加数据

               replcopy:PRIMARY> use testdb

               replcopy:PRIMARY> db.user.insert({name:"wangxiuli"});

               replcopy:PRIMARY> db.user.find();

               { "_id" : ObjectId("576fc8c2e2070e5168bfe7bd"), "name" : "wangxiuli" }


          (2)从节点查看数据是否同步

               replcopy:SECONDARY> use testdb;


               默认从库是不可查询的,但是执行如下语句则可以查询。

               replcopy:SECONDARY> rs.slaveOk();


               replcopy:SECONDARY> db.user.find();

               { "_id" : ObjectId("576fc8c2e2070e5168bfe7bd"), "name" : "wangxiuli" }


          (3)停止主节点

               [root@node1 bin]# kill -2 1659

          

          (4)查看从库状态


               主节点down掉之前,从节点的状态

               replcopy:SECONDARY> rs.status()

               "stateStr" : "SECONDARY",

               主节点down掉之后,从节点的状态

               replcopy:SECONDARY> rs.status()

               "stateStr" : "PRIMARY",

               可以看出来主库down掉之后,从库立马切换为primary状态

          

          (5)此时将主库(192.168.200.140)开启mogo进程会发现已经变为从库

               "state" : 2,

               "stateStr" : "SECONDARY",


                如果我们仍然想让节点1做主库,节点2做从库,我们需要更改优先级。

                修改节点优先级需要登录Master节点运行。否则报错。

               replcopy:PRIMARY> cfg=rs.conf();

               replcopy:PRIMARY> cfg.members[0].priority=10

               replcopy:PRIMARY> cfg.members[1].priority=2

               replcopy:PRIMARY> rs.reconfig(cfg);

               replcopy:PRIMARY> rs.status()


               此时192.168.200.140状态:

               "state" : 1,

               "stateStr" : "PRIMARY",


               192.168.200.144的状态:

               "state" : 2,

               "stateStr" : "SECONDARY",

               


如果不配置仲裁节点,也可实现故障切换,只不过每一台都可能为主或从。而配置了仲裁节点,仲裁节点永远只能为从,不能为主,只参与主库的选举,可作为数据的备份。