目录
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
张贺,多年互联网行业工作经验,担任过网络工程师、系统集成工程师、LINUX系统运维工程师
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
Mongodb副本集
mongodb单台服务器的风险
数据会有丢失的风险
单台服务器无法做高可用性
mongodb副本集能够预防数据丢失,多台mongodb数据一致
mongodb副本集能够在有问题的时候自动切换
1、副本集搭建
环境说明
使用两台服务器实战mongodb副本集,生产环境中建议至少三台服务器
两台服务器的ip为:192.168.237.128、192.168.237.129
下面的环境使用两台服务器创建三个实例:各自侦听在不同的端口
主机 | IP | 端口 |
---|---|---|
M1 | 192.168.80.23 | 27017 |
M2 | 192.168.80.24 | 27018 |
M2 | 192.168.80.24 | 27019 |
M1上的主机操作:
第一步:内核参数优化
echo 'never' >/sys/kernel/mm/transparent_hugepage/enabled
echo 'never' >/sys/kernel/mm/transparent_hugepage/defrag
第二步:将mongodb安装到/usr/local/mongodb目录下,配置文件路径放置在/data/mongodb/27017/mongodb.conf ,配置文件内容如下:
systemLog:
destination: file
logAppend: true
path: /data/mongodb/27017/mongodb.log
storage:
dbPath: /data/mongodb/27017/
journal:
enabled: true
processManagement:
fork: true
net:
port: 27017
bindIp: 0.0.0.0
replication: #仅比单实例多了这两行而已
replSetName: zhanghe #三台实例的名字必须保持一致
M2上主机操作:
第一步:内核参数优化(请参见上一篇博文,此处略过,两台主机保持一致)
echo 'never' >/sys/kernel/mm/transparent_hugepage/enabled
echo 'never' >/sys/kernel/mm/transparent_hugepage/defrag
第二步:将mongodb安装到/usr/local/mongodb目录下,配置文件路径放置在/data/mongodb/27018/mongodb.conf ,配置文件内容如下:
systemLog:
destination: file
logAppend: true
path: /data/mongodb/27018/mongodb.log
storage:
dbPath: /data/mongodb/27018/
journal:
enabled: true
processManagement:
fork: true
net:
port: 27018
bindIp: 0.0.0.0
replication:
replSetName: zhanghe
第三步:另一台实例的配置文件路径放置在/data/mongodb/27019/mongodb.conf ,配置文件内容如下:
systemLog:
destination: file
logAppend: true
path: /data/mongodb/27019/mongodb.log
storage:
dbPath: /data/mongodb/27019/
journal:
enabled: true
processManagement:
fork: true
net:
port: 27019
bindIp: 0.0.0.0
replication:
replSetName: zhanghe
M1上再次操作:
// #定义一个变量config
config = { _id:"zhanghe", members:[
{_id:0,host:"192.168.80.23:27017"},
{_id:1,host:"192.168.80.24:27018"},
{_id:2,host:"192.168.80.24:27019"}]
}
use admin #切换到管理库
rs.initiate( config ) #副本集初始化,需要一定时间,调用config变量
//查看副本集状态,一个primary,其它SECONDARY。primary是主,只有primary能写入
zhanghe:PRIMARY> rs.status()
//在主上插入几行数据,然后去从上测试副本集的数据同步是否实现
use zhang
db.myuser.insert( {userid: 1} )
//查看时延情况,几乎没有时延
zhanghe:PRIMARY> db.myuser.find()
{ "_id" : ObjectId("5e172703c7716c1ae0013a2e"), "userid" : 1 }
zhanghe:PRIMARY> rs.printSlaveReplicationInfo()
source: 192.168.80.24:27018
syncedTo: Thu Jan 09 2020 21:19:46 GMT+0800 (CST)
0 secs (0 hrs) behind the primary
source: 192.168.80.24:27019
syncedTo: Thu Jan 09 2020 21:19:46 GMT+0800 (CST)
0 secs (0 hrs) behind the primary
M2再次操作:
//在主上插入完数据之后,我们去从上面查看,从想要查还需要声明:rs.salveOK(),从库无法插入数据
zhanghe:SECONDARY> rs.slaveOk()
zhanghe:SECONDARY> use zhang
switched to db zhang
zhanghe:SECONDARY> db.myuser.find()
{ "_id" : ObjectId("5e172703c7716c1ae0013a2e"), "userid" : 1 }
2、故障自动切换
mongodb的副本集自动切换
mongodb的副本集当primary挂了,会挑选其中的一台secondary升为主
挑选其中一台secondary升级为primary的条件是剩下的集群台数>=2
如果集群只剩下一个实例的话,会有异常
mongodb副本集自动切换演示
/usr/local/mongodb/bin/mongo 127.0.0.1:27017 #连接到primary
use admin
db.shutdownServer() #关闭主mongodb,会有其它mongodb提升为主。插入数据正常
当主挂了之后,另一台成主,那么当原来的主又启动之后,并不会抢占现在的主,mongodb默认是无抢占的,而且默认主的选择也是随机的,我们可以通过优先级来控制。
mongodb副本集的主的选举
primary的选举依赖于各个实例的优先权重,默认权重都是1
复本集的主挑选权重最高的,权重一样的无法控制谁为主
设置各个实例的优先权重,挑选自己想要的实例为主,只有primary可以更改权重配置
在主上操作:
//在主上看一下优先级都是1,id各有不同
zhanghe:PRIMARY> rs.config()
"_id" : "zhanghe",
"_id" : 0,
"host" : "192.168.80.23:27017",
"priority" : 1
"_id" : 1,
"host" : "192.168.80.24:27018",
"priority" : 1,
"_id" : 2,
"host" : "192.168.80.24:27019",
"priority" : 1,
//将rs.config这个函数的内容赋值给conf,方便我们方便的更改
zhanghe:PRIMARY> conf = rs.config()
//将127.0.0.1:27017的优先级设置为10,就根据rs.config显示的ID
conf.members[0].priority = 10
//将127.0.0.1:27018的优先级设置为5
conf.members[1].priority = 5
//将127.0.0.1:27017的优先级设置为2
conf.members[2].priority = 2
//rs.reconfig(conf) #将config的内容重新读取,让其生效,类似于重新启动重读配置文件
//效果如下所示:
rs.config()
"_id" : 0,
"host" : "192.168.80.23:27017",
"priority" : 10,
"_id" : 1,
"host" : "192.168.80.24:27018",
"priority" : 5,
"_id" : 2,
"host" : "192.168.80.24:27019",
"priority" : 2,
有了优先级,默认就有了抢占,这与几种路由协议的工作原理比较相似。
值得一提的是,当主挂了之后,次优的设备会顶上,当在顶上之前它会先完成自己当前角色的工作,比如B当前是从,主挂了,轮到它登场了,它登场之前一定会先完成从的工作,就是将主的内容全同步完毕,然后才会登场。
3、副本集伸缩
mongodb副本集伸缩说明
-
mongodb副本集的扩展非常好,往副本集里添加实例和移除实例都非常方便
-
往mongodb副本集添加实例数据能够自动同步,无需人工干预
添加一个新的实例
[root@M2 ~]# vim /data/mongodb/27020/mongodb.conf
systemLog:
destination: file
logAppend: true
path: /data/mongodb/27020/mongodb.log
storage:
dbPath: /data/mongodb/27020/
journal:
enabled: true
processManagement:
fork: true
net:
port: 27020
bindIp: 0.0.0.0
replication:
replSetName: zhanghe #注意副本集名称要保持一致replSetName: zhanghe
往现有mongodb副本集中添加实例,注意在主上操作
use admin
rs.add('192.168.80.24:27020') #数据是自动同步
rs.add的优先权重默认为1,可通过rs.config()查看哟!
移除:
从mongodb副本集中移除实例,不可移除primary,如果想移除主的话,先改优先集,改完之后让当前主成为从,然后再移除。
use admin
rs.remove('192.168.80.24:27020')
副本集经过添加删除后顺序会乱,设置权重需要注意rs.config() #获取到后,需要注意每个实例的位置
4、备份和恢复
单台服务器一定需要备份
mongodb有提供mongodump工具用来备份数据,在安装目录的/bin/下
mongodb也有提供mongorestore工具用来恢复数据,在安装目录的/bin/下
mongodb备份说明,指定ip和端口
-
单台服务器直接使用mongodump进行备份
-
副本集需要连接到primary上备份
单实例备份和恢复:
数据清空,启动单台mongodb
systemLog:
destination: file
logAppend: true
path: /data/mongodb/27021/mongodb.log
storage:
dbPath: /data/mongodb/27021/
journal:
enabled: true
processManagement:
fork: true
net:
port: 27021
bindIp: 0.0.0.0
//向这个实例当中随便插入一些数据,方便后面对比。
mongodb数据库的备份,备份所有库
mkdir /data/mongodbbackup/
/usr/local/mongodb/bin/mongodump -h 127.0.0.1:27021 -o /data/mongodbbackup/
mongodb数据库的恢复,恢复到一个新的实例:
/usr/local/mongodb/bin/mongorestore -h 127.0.0.1:27022 /data/mongodbbackup/
//备份完之后查看一下