ongoDB 基础(七)复制

ongodb中的复制可以在多台服务器中同步数据。

复制提供了冗余和增加了数据的高可用性,防止单个节点易丢失数据的可能性,也可以用来进行读写分离提高客户端操作性能。


复制集中各节点的mongodb实例有相同的数据集副本。主节点可以接收客户端所有写操作记录到日志中,从库复制主库的操作日志记录应用到其数据库中。

一个客户端只能有一个主节点,如果主节点不可用(10秒内无法连接),复制集中将选一个成员节点作为主节点。



mongodb复制的基本结构如下:





前期 — 配置服务器名称和IP绑定:


1.  设置服务器名称,3台服务器各自设置自己的主机名(当前终端需重新打开才变化)

[root@mongodb11 ~]# vi/etc/sysconfig/network

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. HOSTNAME= mongodb11.kk.net  

2. 不重启计算机则执行以下方法:

[root@mongodb11 ~]# hostname mongodb11.kk.net


#另两台也更改服务器名称:

HOSTNAME= mongodb12.kk.net

HOSTNAME= mongodb13.kk.net

[root@mongodb12 ~]#hostname mongodb12.kk.net

[root@mongodb13 ~]#hostname mongodb13.kk.net


3. 在3台服务器文件hosts 中都添加以下3行:

# vi /etc/hosts

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 192.168.1.11    mongodb11.kk.net  
  2. 192.168.1.12    mongodb12.kk.net  
  3. 192.168.1.13    mongodb13.kk.net  


实验 — 复制的部署测试:


给3台服务器配置mongodb启动参数(参数如下表格):

[root@mongodb ~]# vi/etc/mongod.conf

192.168.1.11(mongodb11.kk.net)#将作为主库

pidfilepath=/var/run/mongodb/mongod.pid

logpath=/var/log/mongodb/mongod.log

dbpath=/var/lib/mongo

logappend=true

bind_ip=192.168.1.11

port=27017

fork=true

replSet=rs0

192.168.1.12(mongodb12.kk.net)

pidfilepath=/var/run/mongodb/mongod.pid

logpath=/var/log/mongodb/mongod.log

dbpath=/var/lib/mongo

logappend=true

bind_ip=192.168.1.12

port=27018

fork=true

replSet=rs0

192.168.1.13(mongodb13.kk.net)

pidfilepath=/var/run/mongodb/mongod.pid

logpath=/var/log/mongodb/mongod.log

dbpath=/var/lib/mongo

logappend=true

bind_ip=192.168.1.13

port=27019

fork=true

replSet=rs0

配置完成后重启服务:(replSet=rs0  #复制集名称:rs0)

[root@mongodb ~]#service mongod restart


【在192.168.1.11(mongodb11.kk.net)中部署】

1. 登录到mongodb中:

[root@mongodb11 ~]# mongo192.168.1.11:27017


2. 初始化复制集:(集合为:"rs0" ;第一个成员为:"mongodb11.kk.net:27017" )

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. >rs.initiate({_id: "rs0",members: [{ _id: 0 , host: "mongodb11.kk.net:27017" }]})  



3. 添加另2个成员:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. rs.add("mongodb12.kk.net:27018")  
  2. rs.add("mongodb13.kk.net:27019")  



4. 查看成员信息 (或者使用 db.isMaster()    )

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. rs0:PRIMARY> rs.status()  
  2. {  
  3.     "set" : "rs0",  
  4.     "date" : ISODate("2015-05-13T13:56:35.020Z"),  
  5.     "myState" : 1,  
  6.     "members" : [  
  7.         {  
  8.             "_id" : 0,  
  9.             "name" : "mongodb11.kk.net:27017",  
  10.             "health" : 1,  
  11.             "state" : 1,  
  12.             "stateStr" : "PRIMARY",  
  13.             "uptime" : 990,  
  14.             "optime" : Timestamp(1431525353, 1),  
  15.             "optimeDate" : ISODate("2015-05-13T13:55:53Z"),  
  16.             "electionTime" : Timestamp(1431524773, 2),  
  17.             "electionDate" : ISODate("2015-05-13T13:46:13Z"),  
  18.             "configVersion" : 3,  
  19.             "self" : true  
  20.         },  
  21.         {  
  22.             "_id" : 1,  
  23.             "name" : "mongodb12.kk.net:27018",  
  24.             "health" : 1,  
  25.             "state" : 2,  
  26.             "stateStr" : "SECONDARY",  
  27.             "uptime" : 47,  
  28.             "optime" : Timestamp(1431525353, 1),  
  29.             "optimeDate" : ISODate("2015-05-13T13:55:53Z"),  
  30.             "lastHeartbeat" : ISODate("2015-05-13T13:56:33.382Z"),  
  31.             "lastHeartbeatRecv" : ISODate("2015-05-13T13:56:34.022Z"),  
  32.             "pingMs" : 0,  
  33.             "syncingTo" : "mongodb11.kk.net:27017",  
  34.             "configVersion" : 3  
  35.         },  
  36.         {  
  37.             "_id" : 2,  
  38.             "name" : "mongodb13.kk.net:27019",  
  39.             "health" : 1,  
  40.             "state" : 2,  
  41.             "stateStr" : "SECONDARY",  
  42.             "uptime" : 41,  
  43.             "optime" : Timestamp(1431525353, 1),  
  44.             "optimeDate" : ISODate("2015-05-13T13:55:53Z"),  
  45.             "lastHeartbeat" : ISODate("2015-05-13T13:56:33.412Z"),  
  46.             "lastHeartbeatRecv" : ISODate("2015-05-13T13:56:33.467Z"),  
  47.             "pingMs" : 1,  
  48.             "configVersion" : 3  
  49.         }  
  50.     ],  
  51.     "ok" : 1  
  52. }  

或者使用该方法查看,结果也是一样:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. use admin  
  2. db.runCommand( { replSetGetStatus : 1 } )  

详细说明如下:( 参考: replSetGetStatus ) (state 参考 Replica Set Member States

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. "_id" :  #集群中节点编号  
  2. "name" :  #成员服务器名称及端口  
  3. "health" :  #表示成员中的健康状态(0:down;1:up)  
  4. "state" :  #为0~10,表示成员的当前状态  
  5. "stateStr" :  #描述该成员是主库(PRIMARY)还是备库(SECONDARY)  
  6. "uptime" :  #该成员在线时间(秒)  
  7. "optime" :  #成员最后一次应用日志(oplog)的信息  
  8. "optimeDate" :  #成员最后一次应用日志(oplog)的时间  
  9. "electionTime" :  #当前primary从操作日志中选举信息  
  10. "electionDate" :  #当前primary被选定为primary的日期  
  11. "configVersion" :  #mongodb版本  
  12. "self" :  #为true 表示当前节点  




5. 测试操作。在主库中,可以任意操作:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. rs0:PRIMARY> show dbs  
  2. admin  0.078GB  
  3. local  4.076GB  
  4. mydb   0.078GB  
  5. test   0.078GB  
  6. rs0:PRIMARY> use mydb  
  7. switched to db mydb  
  8. rs0:PRIMARY>   
  9. rs0:PRIMARY> db.coll.insert({"id":1})  
  10. WriteResult({ "nInserted" : 1 })  
  11. rs0:PRIMARY>   
  12. rs0:PRIMARY> db.coll.find()  
  13. { "_id" : ObjectId("5553670b60be2bf611868985"), "id" : 1 }  
  14. rs0:PRIMARY>   
  15. rs0:PRIMARY> db.coll.remove({"id":1})  
  16. WriteResult({ "nRemoved" : 1 })  
  17. rs0:PRIMARY>   


【现在到分库中】

192.168.1.12(mongodb12.kk.net)

192.168.1.13(mongodb13.kk.net)


查看分库数据库目录,发现多了几个数据库,数据库与主库(192.168.1.11)一致!是主库同步过来的。

[root@mongodb12 ~]# ll /var/lib/mongo/

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. [root@mongodb13 ~]# ll /var/lib/mongo/  
  2. total 2423844  
  3. -rw-------. 1 mongod mongod   67108864 May 13 21:55 admin.0  
  4. -rw-------. 1 mongod mongod   16777216 May 13 21:55 admin.ns  
  5. drwxr-xr-x. 2 mongod mongod       4096 May 13 21:55 journal  
  6. -rw-------. 1 mongod mongod   67108864 May 13 21:55 local.0  
  7. -rw-------. 1 mongod mongod 2146435072 May 13 23:00 local.1  
  8. -rw-------. 1 mongod mongod   16777216 May 13 23:00 local.ns  
  9. -rwxr-xr-x. 1 mongod mongod          6 May 13 21:40 mongod.lock  
  10. -rw-------. 1 mongod mongod   67108864 May 13 23:00 mydb.0  
  11. -rw-------. 1 mongod mongod   16777216 May 13 23:00 mydb.ns  
  12. -rw-r--r--. 1 mongod mongod         69 May 12 22:05 storage.bson  
  13. -rw-------. 1 mongod mongod   67108864 May 13 21:55 test.0  
  14. -rw-------. 1 mongod mongod   16777216 May 13 21:55 test.ns  
  15. drwxr-xr-x. 2 mongod mongod       4096 May 13 21:55 _tmp  

在副本服务器中登录其本地数据库,发现可以连接,但是无法读写操作:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. [root@mongodb12 ~]# mongo 192.168.1.12:27018  
  2. MongoDB shell version: 3.0.2  
  3. connecting to: 192.168.1.12:27018/test  
  4. rs0:SECONDARY>   

从库开启读操作(此时可以测试主库插入,从库查看,同步正常):

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. rs0:SECONDARY> rs.slaveOk();  


现在模拟主库不可用,将主节点服务停止:

[root@mongodb11 ~]# service mongod stop


到节点192.168.1.12 中登录mongodb,查看复制集状态:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. rs0:SECONDARY> rs.status()  
  2. {  
  3.     "set" : "rs0",  
  4.     "date" : ISODate("2015-05-13T15:44:00.883Z"),  
  5.     "myState" : 2,  
  6.     "members" : [  
  7.         {  
  8.             "_id" : 0,  
  9.             "name" : "mongodb11.kk.net:27017",  
  10.             "health" : 0,  
  11.             "state" : 8,  
  12.             "stateStr" : "(not reachable/healthy)",  
  13.             "uptime" : 0,  
  14.             "optime" : Timestamp(0, 0),  
  15.             "optimeDate" : ISODate("1970-01-01T00:00:00Z"),  
  16.             "lastHeartbeat" : ISODate("2015-05-13T15:43:58.977Z"),  
  17.             "lastHeartbeatRecv" : ISODate("2015-05-13T15:42:16.467Z"),  
  18.             "pingMs" : 0,  
  19.             "lastHeartbeatMessage" : "Failed attempt to connect to mongodb11.kk.net:27017; couldn't connect to server mongodb11.kk.net:27017 (192.168.1.11), connection attempt failed",  
  20.             "configVersion" : -1  
  21.         },  
  22.         {  
  23.             "_id" : 1,  
  24.             "name" : "mongodb12.kk.net:27018",  
  25.             "health" : 1,  
  26.             "state" : 2,  
  27.             "stateStr" : "SECONDARY",  
  28.             "uptime" : 7431,  
  29.             "optime" : Timestamp(1431529249, 1),  
  30.             "optimeDate" : ISODate("2015-05-13T15:00:49Z"),  
  31.             "configVersion" : 3,  
  32.             "self" : true  
  33.         },  
  34.         {  
  35.             "_id" : 2,  
  36.             "name" : "mongodb13.kk.net:27019",  
  37.             "health" : 1,  
  38.             "state" : 1,  
  39.             "stateStr" : "PRIMARY",  
  40.             "uptime" : 6486,  
  41.             "optime" : Timestamp(1431529249, 1),  
  42.             "optimeDate" : ISODate("2015-05-13T15:00:49Z"),  
  43.             "lastHeartbeat" : ISODate("2015-05-13T15:44:00.530Z"),  
  44.             "lastHeartbeatRecv" : ISODate("2015-05-13T15:44:00.091Z"),  
  45.             "pingMs" : 0,  
  46.             "electionTime" : Timestamp(1431531738, 1),  
  47.             "electionDate" : ISODate("2015-05-13T15:42:18Z"),  
  48.             "configVersion" : 3  
  49.         }  
  50.     ],  
  51.     "ok" : 1  
  52. }  


以上信息看到:

原来的主实例(mongodb11.kk.net:27017 )已经无法连接了;

而其中一个节点(mongodb13.kk.net:27019 )变成了主实例,此时该节点是可以读写数据的;


启动服务器 mongodb11.kk.net 的mongodb服务,其变为了副本 (SECONDARY)。


如果想切换回原来的主库,参考:Force a Member to Become Primary

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 1. 使用命令rs.status() 确认数据集成员运行正常  
  2.   
  3. 2. 到次节点192.168.1.12(mongodb12.kk.net)中登录mongodb,运行freeze使其120内不会变为主节点。  
  4. rs.freeze(120)  
  5.   
  6. 3. 到主节点192.168.1.13(mongodb13.kk.net)中强制切换主节点,stepDown将阻止长事务和写入操作  
  7. rs.stepDown(120)  
  8.   
  9. 此时节点192.168.1.11(mongodb11.kk.net)变成主节点  


若要使某个节点永远不会变为主节点,设置优先级为0。(参考 Prevent Secondary from Becoming Primary

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. cfg = rs.conf()  
  2. cfg.members[0].priority = 0.5  
  3. cfg.members[1].priority = 0.5  
  4. cfg.members[2].priority = 0  
  5. rs.reconfig(cfg)  
  6.   
  7.   
  8. 说明:其中成员编号 0/1/2 为 rs.status()中的 "_id"值  
  9. members[2]为192.168.1.13(mongodb13.kk.net),则它将用于不会变成主节点  


移除一个复制成员(两种方法):

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 登录到主库: mongodb11.kk.net ,移除成员  
  2.   
  3. rs.remove("mongodb13.kk.net:27019")  
  4.   
  5.   
  6. 或者:  
  7.   
  8. cfg = rs.conf()  
  9. cfg.members.splice(2,1)  
  10. rs.reconfig(cfg)  

移除后到移除的服务器,更改配置文件 /etc/mongod.conf

#replSet=rs0  #注释

再重启服务,完成移除(数据库文件仍保留在当前服务器)。



更多参考:

Replica Set Deployment Tutorials


Deploy a Replica Set

Deploy a Replica Set for Testing and Development
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值