# MongoDB 副本集集群部署
# MongoDB 集群部署的两种方式
# 配置副本集
# 安装环境
- 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 << EOF > /usr/local/mongodb-4.0.23/mongod.conf
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 << EOF > /usr/lib/systemd/system/mongodb.service
[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 << EOF > /etc/logrotate.d/mongod
/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/
非常感谢以下文章的作者。