MongoDB 数据库高可用解决方案 -- MongoDB复制集(主从复制)
- 前言
- 一、什么是MongoDB复制集 ?
- 二、MongoDB复制集 架构设计
- 三、MongoDB复制集 实战案例
- 1、MongoDB复制集部署
- 2、模拟master故障,实现故障转移、故障恢复
前言
本环境是基于 Centos 7.8 系统构建mongodb-enterprise-4.2.8学习环境
具体构建,请参考 mongodb-enterprise-4.2.8 环境构建
MongoDB复制是将数据同步到多个服务器的过程;复制集提供了数据的冗余备份并提高了数据的可用性,通常可以保证数据的安全性;复制集还允许技术人员从硬件故障和服务中断中恢复数据。
一、什么是MongoDB复制集 ?
什么是复制集
- 保障数据的安全性
- 数据的冗余、备份
- 数据高可用性 (24*7)
- 灾难恢复
- 无需停机维护(如备份,重建索引,压缩)
- 分布式读取数据
- 副本集对应用层是透明的(相对于终端用户)
MongoDB复制集 工作原理
- 1、mongodb的复制集至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。
- 2、mongodb各个节点常见的搭配方式为:一主一从、一主多从。
- 3、主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致
二、MongoDB复制集 架构设计
MongoDB 复制集的特点
- N 个节点的集群
- 任何节点可作为主节点
- 所有写入操作都在主节点上
- 自动故障转移
- 自动恢复
三、MongoDB复制集 实战案例
1、MongoDB复制集部署
环境准备
role | host | ip | mongodb-version |
master | node01 | 192.168.5.11 | mongodb-enterprise-4.2.8 |
slave1 | node02 | 192.168.5.12 | mongodb-enterprise-4.2.8 |
slave2 | node03 | 192.168.5.13 | mongodb-enterprise-4.2.8 |
修改MongoDB配置文件
# 所有节点修改
--- node01
[root@node01 ~]# vim /etc/mongod.conf
net:
port: 27017
bindIp: 127.0.0.1,192.168.5.11
replication:
oplogSizeMB: 1024
replSetName: myRs
[root@node01 ~]# systemctl restart mongod
--- node02
[root@node02 ~]# vim /etc/mongod.conf
net:
port: 27017
bindIp: 127.0.0.1,192.168.5.12
replication:
oplogSizeMB: 1024
replSetName: myRs
[root@node02 ~]# systemctl restart mongod
--- node03
[root@node03 ~]# vim /etc/mongod.conf
net:
port: 27017
bindIp: 127.0.0.1,192.168.5.13
replication:
oplogSizeMB: 1024
replSetName: myRs
[root@node03 ~]# systemctl restart mongod
配置主节点
# 登录MongoDB
[root@node01 ~]# mongo
MongoDB shell version v4.2.8
# 查看ReplSet状态
MongoDB Enterprise > rs.status()
{
"operationTime" : Timestamp(0, 0),
"ok" : 0,
"errmsg" : "no replset config has been received",
"code" : 94,
"codeName" : "NotYetInitialized",
"$clusterTime" : {
"clusterTime" : Timestamp(0, 0),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
# 初始化ReplSet复制集
MongoDB Enterprise > rs.initiate({_id:'myRS',members:[{_id:1,host:'192.168.5.11:27017'}]})
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1613533287, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1613533287, 1)
}
再次查看ReplSet状态
主上增加从节点
MongoDB Enterprise myRS:PRIMARY> rs.add('192.168.5.12:27017','192.168.5.13:27017')
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1613534429, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1613534429, 1)
}
查看ReplSet状态
主节点插入数据,测试主从同步
主插入数据
# 插入数据
MongoDB Enterprise myRS:PRIMARY> use test
switched to db test
MongoDB Enterprise myRS:PRIMARY> for(var i =0; i <4; i ++){db.user.insert({userName:'my'+i,age:i})}
WriteResult({ "nInserted" : 1 })
# 查看数据
MongoDB Enterprise myRS:PRIMARY> db.user.find()
{ "_id" : ObjectId("602c98c21b314e8e6e90e15a"), "userName" : "my0", "age" : 0 }
{ "_id" : ObjectId("602c98c21b314e8e6e90e15b"), "userName" : "my1", "age" : 1 }
{ "_id" : ObjectId("602c98c21b314e8e6e90e15c"), "userName" : "my2", "age" : 2 }
{ "_id" : ObjectId("602c98c21b314e8e6e90e15d"), "userName" : "my3", "age" : 3 }
slave01查看
slave02查看
MongoDB复制集成功!!!
2、模拟master故障,实现故障转移、故障恢复
模拟关闭主节点
MongoDB Enterprise myRS:PRIMARY> use admin
switched to db admin
MongoDB Enterprise myRS:PRIMARY> db.shutdownServer()
2021-02-17T12:30:51.021+0800 I NETWORK [js] DBClientConnection failed to receive message from 127.0.0.1:27017 - HostUnreachable: Connection closed by peer
server should be down...
2021-02-17T12:30:51.038+0800 I NETWORK [js] trying reconnect to 127.0.0.1:27017 failed
2021-02-17T12:30:51.038+0800 I NETWORK [js] reconnect 127.0.0.1:27017 failed failed
2021-02-17T12:30:51.042+0800 I NETWORK [js] trying reconnect to 127.0.0.1:27017 failed
2021-02-17T12:30:51.042+0800 I NETWORK [js] reconnect 127.0.0.1:27017 failed failed
MongoDB Enterprise >
node03查看
node02切换为master
node02查看插入三条记录
[root@node02 ~]# mongo
MongoDB shell version v4.2.8
MongoDB Enterprise myRS:PRIMARY> use test
switched to db test
MongoDB Enterprise myRS:PRIMARY> for(var i =4; i <7; i ++){db.user.insert({userName:'my'+i,age:i})}
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise myRS:PRIMARY> db.user.find()
{ "_id" : ObjectId("602c98c21b314e8e6e90e15a"), "userName" : "my0", "age" : 0 }
{ "_id" : ObjectId("602c98c21b314e8e6e90e15b"), "userName" : "my1", "age" : 1 }
{ "_id" : ObjectId("602c98c21b314e8e6e90e15c"), "userName" : "my2", "age" : 2 }
{ "_id" : ObjectId("602c98c21b314e8e6e90e15d"), "userName" : "my3", "age" : 3 }
{ "_id" : ObjectId("602c9d4a2db6914f63068e15"), "userName" : "my4", "age" : 4 }
{ "_id" : ObjectId("602c9d4a2db6914f63068e16"), "userName" : "my5", "age" : 5 }
{ "_id" : ObjectId("602c9d4a2db6914f63068e17"), "userName" : "my6", "age" : 6 }
node03查看
启动master
[root@node01 ~]# systemctl start mongod
[root@node01 ~]# systemctl is-active mongod
active
node03查看主从状态
node01已经切换到salve状态
node02再次插入三条数据
MongoDB Enterprise myRS:PRIMARY> use test
switched to db test
MongoDB Enterprise myRS:PRIMARY> for(var i =7; i <10; i ++){db.user.insert({userName:'my'+i,age:i})}
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise myRS:PRIMARY> db.user.find()
{ "_id" : ObjectId("602c98c21b314e8e6e90e15a"), "userName" : "my0", "age" : 0 }
{ "_id" : ObjectId("602c98c21b314e8e6e90e15b"), "userName" : "my1", "age" : 1 }
{ "_id" : ObjectId("602c98c21b314e8e6e90e15c"), "userName" : "my2", "age" : 2 }
{ "_id" : ObjectId("602c98c21b314e8e6e90e15d"), "userName" : "my3", "age" : 3 }
{ "_id" : ObjectId("602c9d4a2db6914f63068e15"), "userName" : "my4", "age" : 4 }
{ "_id" : ObjectId("602c9d4a2db6914f63068e16"), "userName" : "my5", "age" : 5 }
{ "_id" : ObjectId("602c9d4a2db6914f63068e17"), "userName" : "my6", "age" : 6 }
{ "_id" : ObjectId("602c9f71912509e6bd44076c"), "userName" : "my7", "age" : 7 }
{ "_id" : ObjectId("602c9f71912509e6bd44076d"), "userName" : "my8", "age" : 8 }
{ "_id" : ObjectId("602c9f71912509e6bd44076e"), "userName" : "my9", "age" : 9 }
node01查看数据
node03查看数据
故障切换、故障恢复成功实现!!!