MongoDB 集群部署的两种方式
1. MongoDB 主从复制(已废弃)
主从模式(master-slave)是 MongoDB 最早使用的复制方式,在新版的 Mongo 中已经被移除。
从 MongoDB 3.2 版本开始,主从复制被废弃。
https://docs.mongodb.com/v3.2/core/master-slave/
在 MongoDB 4.0 及以后版本,主从复制被移除。
https://docs.mongodb.com/v4.0/core/master-slave/
2. MongoDB 副本集
MongoDB副本集(Replica Set)其实就是具有自动故障恢复功能的主从集群,和主从复制最大的区别就是在副本集中没有固定的“主节点”,整个副本集会选出一个节点作为“主节点”,当其挂掉后,再在剩下的从节点中选举一个节点成为新的“主节点”,在副本集中总有一个主节点(primary)和一个或多个备份节点(secondary)。
除了 primary 和 secondary 之外,副本集中的节点还可以是以下角色:
成为 primary | 对客户端可见 | 参与投票 | 延迟同步 | 复制数据 | |
---|---|---|---|---|---|
Default | ✔ | ✔ | ✔ | ✘ | ✔ |
Secondary-Only | ✘ | ✔ | ✔ | ✘ | ✔ |
Hidden | ✘ | ✘ | ✔ | ✘ | ✔ |
Delayed | ✘ | ✔ | ✔ | ✔ | ✔ |
Arbiters | ✘ | ✘ | ✔ | ✘ | ✘ |
Non-Voting | ✔ | ✔ | ✘ | ✘ | ✔ |
关于副本集的基础概念,可以参考:https://blog.csdn.net/pengjunlee/article/details/83958794
官方帮助文档:https://docs.mongodb.com/manual/replication/
官方推荐的副本集最小配置需要有三个节点:一个主节点接收和处理所有的写操作,两个备份节点通过复制主节点的操作来对主节点的数据进行同步备份。
配置副本集
安装环境
- 3 台服务器,官方推荐副本集部署至少需要 3 个节点
- 操作系统:CentOS 7.x
- MongoDB:4.0.x
副本集各节点 IP 如下:
192.168.202.131
192.168.202.132
192.168.202.133
安装 MongoDB 服务器
1、下载 MongoDB 安装包
curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.23.tgz
2、解压安装
tar -xf mongodb-linux-x86_64-4.0.23.tgz
mv mongodb-linux-x86_64-4.0.23 /usr/local/mongodb-4.0.23
3、创建数据目录、日志目录
mkdir /usr/local/mongodb-4.0.23/{data,log}
4、创建配置文件,设置副本集名称(各个节点副本集名称相同)
cat > /usr/local/mongodb-4.0.23/mongod.conf << EOF
systemLog:
destination: file
path: /usr/local/mongodb-4.0.23/log/mongod.log
logAppend: true
# 日志分割
#logRotate: reopen
# 副本集设置
replication:
replSetName: rs1
# oplogSizeMB: 10240
#security:
# authorization: enabled
# keyFile: /usr/local/mongodb-4.0.23/keyfile
storage:
dbPath: /usr/local/mongodb-4.0.23/data
processManagement:
fork: true
pidFilePath: /var/run/mongod.pid
net:
bindIp: 0.0.0.0
port: 27017
maxIncomingConnections: 65535
EOF
5、设置 MongoDB 系统服务
cat > /usr/lib/systemd/system/mongodb.service << EOF
[Unit]
Description=mongodb
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
ExecStart=/usr/local/mongodb-4.0.23/bin/mongod --config /usr/local/mongodb-4.0.23/mongod.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/usr/local/mongodb-4.0.23/bin/mongod --shutdown --config /usr/local/mongodb-4.0.23/mongod.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
6、刷新 systemctl 服务
systemctl daemon-reload
7、设置开机自启
systemctl enable mongodb
查看开机自启是否设置成功
systemctl list-unit-files | grep mongodb
8、启动 MongoDB 服务
systemctl start mongodb
9、关闭防火墙或者开放 27017 端口
至此,3 个 MongoDB 实例都已经以副本集方式启动,但它们彼此之间现在还不会进行通信,仍需要进行一些配置。
副本集初始化
通过 Shell 连接到任意一个 MongoDB 实例,执行 rs.initiate() 方法对副本集进行初始化。
/usr/local/mongodb-4.0.23/bin/mongo 192.168.202.131:27017
// priority 为权重,默认值是1,权重大的会被置为 Primary 节点
conf = {
_id: "rs1",
members: [
{ _id: 0, host: "192.168.202.131:27017", priority: 5 },
{ _id: 1, host: "192.168.202.132:27017", priority: 3 },
{ _id: 2, host: "192.168.202.133:27017", priority: 1 }
]
}
rs.initiate(conf)
如果在执行 rs.initiate() 方法时不传入任何参数,MongoDB 将以默认的配置文档对副本集进行初始化,后续可以再通过 rs.add() 方法来向副本集中添加成员。
副本集更新
// 向副本集中添加成员
rs.add("192.168.202.150:27017")
// 从副本集中删除成员
rs.remove("192.168.202.150:27017")
// 向副本集中添加仲裁
rs.addArb("192.168.202.150:27017")
// 向副本集中添加备份节点
rs.add({ _id: 3, host: "192.168.202.150:27017", priority: 0, hidden: true })
# 更改副本集配置
rs1:PRIMARY> var conf = rs.conf()
rs1:PRIMARY> conf.members[1].priority = 10
# PRIMARY 节点上执行如下命令
rs1:PRIMARY> rs.reconfig(conf)
# 如果在 SECONDARY节点上执行上面的命令,需增加 force 参数
rs1:SECONDARY> rs.reconfig(conf, { force: true })
强制让一个节点成为 Primary,可以将该节点的优先级设置成最高。
conf = rs.conf()
conf.members[0].priority = 5
conf.members[1].priority = 1
conf.members[2].priority = 1
rs.reconfig(conf)
副本集监控
1、查看副本集的配置信息
rs1:PRIMARY> rs.conf()
2、查看副本集运行状态
rs1:PRIMARY> rs.status()
3、查看备份节点的复制信息
rs1:PRIMARY> db.printSecondaryReplicationInfo()
副本集测试
复制测试
1、在 Primary 上插入 10 条客户数据:
rs1:PRIMARY> for(var i = 0; i < 10; i++) { db.customer.insert({name: "user" + i }) }
2、在 Secondary 上查看客户数据是否已经同步:
rs1:SECONDARY> rs.secondaryOk()
rs1:SECONDARY> db.customer.count() # 10
故障转移测试
1、查看 Primary 节点关闭之前的状态
rs1:PRIMARY> rs.status()
2、执行如下命令关闭 Primary 节点,查看其他 2 个节点的情况
systemctl stop mongodb
3、在任意其他节点上查看 Primary 节点关闭之后的状态
rs.status()
4、再次启动 192.168.202.131:27017 节点,由于其选举优先级最高,自动被选举为 Primary
// 待 192.168.202.131:27017 节点启动后再次查看副本集状态
rs.status()
开启安全认证
创建用户
登录 PRIMARY 节点创建用户,在此我们创建以下两个用户:
- root:超级管理员,对数据库拥有完全管理权限
- admin:对所有数据库表有读写权限
rs1:PRIMARY> show dbs
admin 0.000GB
config 0.000GB
local 0.001GB
test 0.000GB
rs1:PRIMARY> use admin
switched to db admin
# 创建 root 用户
rs1:PRIMARY> db.createUser({ user: "root", pwd: "root123", roles: [{ role: "root", db: "admin" }] })
# 创建 admin 用户
rs1:PRIMARY> db.createUser({ user: "admin", pwd: "admin123", roles: [{ role: "readWriteAnyDatabase", db: "admin" }] })
创建 keyFile 文件
1、先停掉所有 SECONDARY 节点的 MongoDB 服务,然后再停掉 PRIMARY 节点的 MongoDB 服务
systemctl stop mongodb
2、在 PRIMARY 节点所在服务器上创建 keyFile 文件。
openssl rand -base64 666 > /usr/local/mongodb-4.0.23/keyfile
chmod 600 /usr/local/mongodb-4.0.23/keyfile
3、将生成的 keyFile 文件拷贝到其他节点服务器上,并修改文件的操作权限为 600
cd /usr/local/mongodb-4.0.23/
scp keyfile root@192.168.202.132:`pwd`
scp keyfile root@192.168.202.133:`pwd`
# 在另外两个节点修改 keyfile 文件权限
chmod 600 /usr/local/mongodb-4.0.23/keyfile
更新启动配置文件
1、修改 PRIMARY 节点的 mongodb.conf 文件,增加如下内容
replication:
oplogSizeMB: 10240
security:
authorization: enabled
keyFile: /usr/local/mongodb-4.0.23/keyfile
快速修改
sed -i 's/# oplogSizeMB/ oplogSizeMB/g' /usr/local/mongodb-4.0.23/mongod.conf && \
sed -i 's/#security/security/g' /usr/local/mongodb-4.0.23/mongod.conf && \
sed -i 's/# authorization/ authorization/g' /usr/local/mongodb-4.0.23/mongod.conf && \
sed -i 's/# keyFile/ keyFile/g' /usr/local/mongodb-4.0.23/mongod.conf
2、修改 SECONDARY 节点的 mongodb.conf 文件,增加如下内容
replication:
oplogSizeMB: 10240
security:
keyFile: /usr/local/mongodb-4.0.23/keyfile
快速修改
sed -i 's/# oplogSizeMB/ oplogSizeMB/g' /usr/local/mongodb-4.0.23/mongod.conf && \
sed -i 's/#security/security/g' /usr/local/mongodb-4.0.23/mongod.conf && \
sed -i 's/# keyFile/ keyFile/g' /usr/local/mongodb-4.0.23/mongod.conf
启动副本集
1、先以 --auth 方式启动 PRIMARY 节点
systemctl start mongodb
2、再启动 SECONDARY 节点
systemctl start mongodb
登录测试
/usr/local/mongodb-4.0.23/bin/mongo \
-uadmin -padmin123 \
--authenticationDatabase admin \
192.168.202.131:27017
日志分割
MongoDB 默认是没有进行日志分割的,所有的日志持续写到一个文件中。缺点是很明显的,日志文件会越来越大:
- 占用过多磁盘空间
- 日志文件写入性能越来越低
- 问题排查越来越困难
配置分割策略
修改各个节点的 mongodb.conf 文件,增加如下内容
systemLog:
logRotate: reopen
快速修改
sed -i 's/ #logRotate/ logRotate/g' /usr/local/mongodb-4.0.23/mongod.conf
使用 Linux/Unix 系统的 logRotate 工具分割日志
1、在 /etc/logrotate.d/ 目录下新建一个名为 mongod 的文件
cat > /etc/logrotate.d/mongod << EOF
/usr/local/mongodb-4.0.23/log/*.log {
create 0644 root root
# 按日切分
daily
# 最多保留90个
rotate 90
# 切分文件加日期后缀
dateext
# 没有就不执行
missingok
# 空的就不执行
notifempty
sharedscripts
postrotate
# 切分完成后, 通知 MongoDB 重开文件
/bin/kill -USR1 \`cat /run/mongod.pid 2>/dev/null\` 2>/dev/null || true
endscript
}
EOF
2、这个配置文件的权限必须为 -rw-r--r--
,不然 logrotate 不认
chmod 644 /etc/logrotate.d/mongod
3、测试日志分割
logrotate -f /etc/logrotate.d/mongod
ls /usr/local/mongodb-4.0.23/log/
非常感谢以下文章的作者。
(完)