date: 2020-03-24title: mongodb复制 #标题
tags: mongodb #标签
categories: mongodb # 分类

参考文档:菜鸟教程

mongodb复制原理

mongodb的复制最少需要两个节点,一个master,用于处理用户的请求,其余都是从节点,负责复制主节点上的数据。

mongodb常见集群环境:一主一从、一主多从。

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

MongoDB复制结构图如下:

mongodb复制 - 图1

在上面的架构中,客户端从primary读取数据,在客户端写入数据到primary时,primary与secondary进行数据交互保障数据的一致性。

mongodb的副本有以下特征:

  • N 个节点的集群
  • 任何节点可作为主节点
  • 所有写入操作都在主节点上
  • 自动故障转移
  • 自动恢复

环境准备

OS IP 角色
Centos 7.5 192.168.20.2 master
Centos 7.5 192.168.20.5 slave1
Centos 7.5 192.168.20.6 slave2

配置mongodb群集

修改配置文件

  1. [root@slave2 ~]# mongo --version # mongodb版本如下
  2. MongoDB shell version v4.2.3
  3. [root@master ~]# cat /data/mongodb/27017/mongodb.conf # 查看mongodb配置文件
  4. systemLog:
  5. destination: file
  6. logAppend: true
  7. path: /data/mongodb/27017/mongodb.log
  8. storage:
  9. dbPath: /data/mongodb/27017/
  10. journal:
  11. enabled: true
  12. processManagement:
  13. fork: true
  14. net:
  15. port: 27017
  16. bindIp: 0.0.0.0
  17. # 添加如下两行配置
  18. replication:
  19. replSetName: test_cluster # 指定复制名称为replication(参与复制的节点指定的此名称必须一致)。

参与复制的节点配置文件都需要写上面两行配置,自行修改其他节点的配置文件即可。

修改配置文件后,自行重启mongodb,以便修改生效。

初始化集群

  1. # 登录到mongodb数据库中,进行以下操作
  2. > use admin
  3. switched to db admin
  4. # 定义变量,下面ID就是配置文件中指定的副本集名称,members是一个数组,指定的是参与复制的所有节点监听地址及端口
  5. > config = {_id:"test_cluster",members:[
  6. ... {_id:0,host:"192.168.20.2:27017"},
  7. ... {_id:1,host:"192.168.20.5:27017"},
  8. ... {_id:2,host:"192.168.20.6:27017"}]
  9. ... }
  10. # 引用变量config,初始化集群
  11. > rs.initiate(config) # 此指令必须在admin库中进行配置
  12. > rs.initiate(config)
  13. {
  14. "ok" : 1, # 返回ok的值为1,则表示配置成功
  15. # 群集配置成功后,命令提示符也会发生变化
  16. test_cluster:SECONDARY> # 一开始所有节点都是secondary
  17. test_cluster:PRIMARY> # 经过选举后,会选出primary,也就是主节点

配置secondary可读

配置复制后,默认secondary会复制当前primary的数据,并且secondary是不允许进行读写操作的。

当副本集初始化完成后,还需要在secondary上声明自己是从节点,才能查看数据。如下:

  1. test_cluster:SECONDARY> rs.slaveOk()

集群状态相关查询

查看secondary延迟情况

  1. test_cluster:PRIMARY> rs.printSlaveReplicationInfo()
  2. source: 192.168.20.5:27017
  3. syncedTo: Tue Mar 24 2020 18:45:51 GMT+0800 (CST)
  4. 0 secs (0 hrs) behind the primary # 这里显示延迟的秒数
  5. source: 192.168.20.6:27017
  6. syncedTo: Tue Mar 24 2020 18:45:51 GMT+0800 (CST)
  7. 0 secs (0 hrs) behind the primary

查看副本集状态

  1. test_cluster:SECONDARY> rs.status()

验证数据复制

  1. # 登录到primary节点插入数据
  2. test_cluster:PRIMARY> use mytest
  3. test_cluster:PRIMARY> db.myuser.insert({name:"zhangsan",age:25})
  4. test_cluster:PRIMARY> db.myuser.find()
  5. { "_id" : ObjectId("5e79e68b6c86e8d2435675c2"), "name" : "zhangsan", "age" : 25 }
  6. # seconday节点进行查询验证
  7. test_cluster:SECONDARY> use mytest
  8. test_cluster:SECONDARY> db.myuser.find()
  9. { "_id" : ObjectId("5e79e68b6c86e8d2435675c2"), "name" : "zhangsan", "age" : 25 }

副本集的优先级

MongoDB 副本集的中,Secondary 会不断检测 Primary 的健康状况,一旦 Primary 故障,各 Secondary会根据优先级来选举一个新的Primary。在没有指定优先级的情况下,各实例的优先级为1,在优先级一样的情况下,无法预料到底哪个secondary会成为primary。

获取副本集的配置信息,各实例的优先级默认为1

  1. test_cluster:PRIMARY> conf = rs.config() # 将查询状态的指令定义为变量方便调用
  2. # 定义各节点的优先级
  3. test_cluster:PRIMARY> conf.members[0].priority = 10
  4. 10
  5. test_cluster:PRIMARY> conf.members[1].priority = 5
  6. 5
  7. test_cluster:PRIMARY> conf.members[2].priority = 2
  8. 2
  9. test_cluster:PRIMARY> rs.reconfig(conf) # 刷新配置
  10. test_cluster:PRIMARY> rs.config().members # 查看各实例当前的优先级

测试mongodb自动故障转移

在上面的优先级配置阶段,设置的当前primary的优先级为10,所以primary的角色没有发生改变,那么如果当前primary节点宕机呢?会不会按照我们的配置,将id为1的节点提升为primary(它的优先级为5,比另一个节点的优先级2要高)。

  1. # 在primary节点停掉该实例
  2. test_cluster:PRIMARY> use admin
  3. test_cluster:PRIMARY> db.shutdownServer()
  4. # 到优先级为2的节点,敲下回车,会发现命令提示符已经变了,如下:
  5. test_cluster:SECONDARY>
  6. test_cluster:PRIMARY>

副本集的伸缩

新增一个mongodb,监听地址为:192.168.20.2:28018,配置文件参考前几个节点的配置文件(注意配置文件中的副本集名称要保持一致)。

MongoDB 副本集里添加实例和移除实例都非常方便,往 MongoDB 副本集添加实例数据能够自动同步,无需人工干预添加实例。数据是自动同步,rs.add 的优先权重默认是 1

  1. # 增加节点
  2. test_cluster:PRIMARY> use admin
  3. test_cluster:PRIMARY> rs.add("192.168.20.2:28018") # 添加新节点
  4. # 删除节点(不可删除primary节点)
  5. test_cluster:PRIMARY> rs.remove("192.168.20.2:28018")

注:副本集经过添加删除后顺序会乱,设置权重需要注意。

mongodb的数据备份与恢复

备份指令

  1. >mongodump -h dbhost -d dbname -o dbdirectory

各指令解释如下:

  • -h:MongDB 所在服务器地址,例如:127.0.0.1,也可以指定端口号:127.0.0.1:27017
  • -d:需要备份的数据库实例,例如:mytest
  • -o:备份的数据存放位置,例如:/data/mongobackup/,当然该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个备份的db名称的目录,这个目录里面存放该数据库实例的备份数据。

实例:

  1. # 备份mytest集合
  2. [root@master mongodb]# mongodump -h 192.168.20.2:27017 -d mytest -o /data/mongobackup
  3. # 查看备份文件
  4. [root@master mongobackup]# pwd
  5. /data/mongobackup
  6. [root@master mongobackup]# ls mytest/
  7. myuser.bson myuser.metadata.json

恢复数据库

命令格式如下:

  1. >mongorestore -h dbhost -d dbname 存放备份数据的目录

各项指令解释如下:

  • -h:MongoDB 所在服务器地址
  • -d:需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如 mytest

实例:

  1. # 进入mytest删除这个库(但需要有这个库的备份)
  2. test_cluster:PRIMARY> use mytest
  3. test_cluster:PRIMARY> db.dropDatabase()
  4. # 到本地进行数据库恢复
  5. [root@master ~]# mongorestore -h 192.168.20.2:27017 -d lv_test /data/mongobackup/mytest/