4. MongoDB部署
4.1 可复制集
可复制集是跨多个 MongDB 服务器(节点)分布和维护数据的方法。mongoDB 可以把数据 从一个节点复制到其他节点并在修改时进行同步,集群中的节点配置为自动同步数据;旧方 法叫做主从复制,mongoDB 3.0 以后推荐使用可复制集;
为什么要用可复制集?它有什么重要性?
-
避免数据丢失,保障数据安全,提高系统安全性; (最少 3 节点,最大 50 节点)
-
自动化灾备机制,主节点宕机后通过选举产生新主机;提高系统健壮性;(7 个选举节点上限)
-
读写分离,负载均衡,提高系统性能;
-
生产环境推荐的部署模式;
4.4.1. 可复制集架构以及原理

-
oplog(操作日志):保存操作记录、时间戳
-
数据同步:从节点与主节点保持长轮询;1.从节点查询本机 oplog 最新时间戳;2.查询主节点 oplog 晚于此时间戳的所有文档;3.加载这些文档,并根据 log 执行写操作;
-
阻塞复制:与 writeconcern 相关,不需要同步到从节点的策略(如: acknowledged Unacknowledged 、w1),数据同步都是步的,其他情况都是同步;
-
心跳机制:成员之间会每 2s 进行一次心跳检测(ping 操作),发现故障后进行选举和故障转移;
-
选举制度:主节点故障后,其余节点根据优先级和 bully 算法选举出新的主节点,在选出主节点之前,集群服务是只读的
oplog 是盖子集合,大小是可以调整的,默认是所在硬盘 5%;
https://docs.mongodb.com/manual/reference/configuration-options/
4.4.2. 可复制集的搭建过程
安装好 3 个以上节点的 mongoDB;
# 创建三个db目录
mkdir ./data/{db1,db2,db3}
# 创建三个log目录
mkdir ./log/{log1,log2,log3}
# 创建三个配置目录
mkdir -r ./conf/{node1,node2,node3}
# 同时复制配置到三个目录中
echo ./conf/node1 ./conf/node2 ./conf/node3 | xargs -n 1 cp -v ./conf/mgdb.conf
# 修改端口, db,log路径配置
vim ./conf/node1/mgdb.conf
下面是老版本的配置方式
#数据文件存放目录
dbpath=/root/mongo/mongo/data/db1
#日志文件存放目录
logpath=/root/mongo/mongo/log/log1/mongodb.log
#端口,默认 27017,可以自定义, 避免和本地的27017端口冲突导致连接不上远程的mongo服务
port=27018
#开启日志追加添加日志
logappend=true
#以守护程序的方式启用,即在后台运行
fork=true
#本地监听 IP,0.0.0.0 表示本地所有 IP
bind_ip=0.0.0.0
#是否需要验证权限登录(用户名和密码)
auth=false
下面是新版本的配置
storage:
dbPath: "/root/mongo/mongo/data/db1"
systemLog:
destination: file
path: "/root/mongo/mongo/log/log1/mongodb.log"
net:
bindIp: 0.0.0.0
port: 27017
processManagement:
fork: true
setParameter:
enableLocalhostAuthBypass: false
按照新版本配置复制集
配置 mgdb.conf,增加跟复制相关的配置如下:
replication:
replSetName: configRS //集群名称
oplogSizeMB: 50 //oplog集合大小
启动命令
mongod --config ./mongo/conf/node1/mgdb.conf &
mongod --config ./mongo/conf/node2/mgdb.conf &
mongod --config ./mongo/conf/node3/mgdb.conf &
在主节点配置
在 primary 节点切换到 admin 库上运行可复制集的初始化命令,初始化可复制集,命令如下: mongo --port 27018
注意: mongo -p 27018
是一个错误命令, 如果你本地启动了一个27017的mongo进程, 那么, 这个命令可以进入, 但是她进入的不是复制集, 是使用27017端口的那个进程
rs: replica set
rs.initiate({
_id: "configRS", version: 1, members: [{
_id: 0, host : "192.168.125.132:27018" }]}); rs.add("192.168.125.132:27019"); //有几个节点就执行几次方法
rs.add("192.168.125.132:27020"); //有几个节点就执行几次方法
-
在每个节点运行 rs.status()或 rs.isMaster()命令查看复制集状态;
-
测试数据复制集效果;
-
测试故障失效转移效果;
只能在主节点查询数据,但如果想在副节点查询到数据需运行 rs.slaveOk();
不执行rs.slaveOk()将会报错 not master and slaveOk=false
configRS:SECONDARY> show dbs
2022-08-24T07:48:42.162-0700 E QUERY [js] Error: listDatabases failed:{
"operationTime" : Timestamp(1661352516, 1),
"ok" : 0,
"errmsg" : "not master and slaveOk=false",