MongoDB搭建集群
单机版MongoDB隐患
没有灾备能力:在单节点宕机的情况下,服务不可用会拖垮整个系统;
吞吐量不够:系统并发较高、访问量过大时,单节点无法承载流量;
拓展性不足:只能通过升级单节点的硬件配置,无法横向拓展;
数据安全风险:在极端情况下,数据损坏或出现丢失,无法有效恢复。
副本集群介绍
MongoDB副本集群,也被称之为复制集群,内在含义是:一个主节点拥有读写能力,一或多个从节点全量拷贝主节点的数据,对外提供读的能力
MongoDB副本集群,在主节点发生故障的情况下,无需任何外力介入,能自动完成主从切换,从而对外实现真正意义上的7*24h高可用,并且从节点还可以处理读请求,从而保障MongoDB服务的高性能。
MongoDB三个节点角色
Primary主节点:拥有读写能力,为集群内的副本节点,提供数据拷贝的支持;
Replicate副本节点:拥有读能力,数据完全拷贝自主节点,即主从概念中的从节点;
Arbiter仲裁节点:不具备读写能力,用于故障恢复,提供故障检测、选举投票能力。
仲裁节点:作用等同于哨兵节点,但它并不是副本集群必须存在的节点,因为主节点、副本节点都拥有投票能力,它的存在只是为了维护集群内的平衡,如集群节点为偶数时,可以添加一个仲裁节点,让集群保持奇数特性,确保每轮选举一次就能推出新主,避免多轮无效竞选的现象出现
集群搭建
机器准备(已设置环境变量)
集群模式
单机模式:一台机器对外提供服务;
集群模式:多台机器对外提供同一服务;
伪集群模式:单台机器上启动多个实例,模拟多机器场景对外提供服务。
集群搭建
编写主节点的配置文件
# ============================================================
# MongoDB 副本集配置文件 - 主节点(PRIMARY)
# IP: 192.168.7.101
# 端口: 27017
# 角色: 主节点(可读写)
# ============================================================
# ---------- 系统日志配置 ----------
systemLog:
# destination: 日志输出目标,file 表示输出到文件
destination: file
# path: 日志文件的完整路径
path: "/usr/local/mongodb/log/standalone/mongodb.log"
# logAppend: true 表示每次重启时追加到现有日志文件末尾,而非覆盖
logAppend: true
# ---------- 存储配置 ----------
storage:
# dbPath: MongoDB 数据文件存储目录
dbPath: "/usr/local/mongodb/data/standalone"
# ---------- 进程管理配置 ----------
processManagement:
# fork: true 表示以后台守护进程方式运行(后台运行)
fork: true
# pidFilePath: 保存进程ID(PID)的文件路径,用于管理进程
pidFilePath: "/usr/local/mongodb/conf/mongod.pid"
# ---------- 网络配置 ----------
net:
# bindIp: 绑定监听的IP地址
# 0.0.0.0 表示监听所有网络接口(允许任何IP连接)
# 生产环境建议改为具体IP,如 192.168.7.101
bindIp: 0.0.0.0
# port: MongoDB 服务监听的端口号,默认 27017
port: 27017
# ---------- 副本集配置 ----------
replication:
# replSetName: 副本集名称,三台服务器必须保持一致
# 这里命名为 rs0(replica set 0 的缩写)
replSetName: rs0编写从节点的配置文件
# ============================================================
# MongoDB 副本集配置文件 - 从节点(SECONDARY)
# IP: 192.168.7.102
# 端口: 27017
# 角色: 从节点(只读,自动同步主节点数据)
# ============================================================
# ---------- 系统日志配置 ----------
systemLog:
# destination: 日志输出目标,file 表示输出到文件
destination: file
# path: 日志文件的完整路径
path: "/usr/local/mongodb/log/standalone/mongodb.log"
# logAppend: true 表示每次重启时追加到现有日志文件末尾,而非覆盖
logAppend: true
# ---------- 存储配置 ----------
storage:
# dbPath: MongoDB 数据文件存储目录
dbPath: "/usr/local/mongodb/data/standalone"
# ---------- 进程管理配置 ----------
processManagement:
# fork: true 表示以后台守护进程方式运行(后台运行)
fork: true
# pidFilePath: 保存进程ID(PID)的文件路径,用于管理进程
pidFilePath: "/usr/local/mongodb/conf/mongod.pid"
# ---------- 网络配置 ----------
net:
# bindIp: 绑定监听的IP地址
# 0.0.0.0 表示监听所有网络接口(允许任何IP连接)
# 生产环境建议改为具体IP,如 192.168.7.102
bindIp: 0.0.0.0
# port: MongoDB 服务监听的端口号,默认 27017
port: 27017
# ---------- 副本集配置 ----------
replication:
# replSetName: 副本集名称,三台服务器必须保持一致
# 这里命名为 rs0(replica set 0 的缩写)
replSetName: rs0编写仲裁节点的配置文件
# ============================================================
# MongoDB 副本集配置文件 - 仲裁节点(ARBITER)
# IP: 192.168.7.100
# 端口: 27017
# 角色: 仲裁节点(不存储数据,仅参与主节点选举投票)
# 作用: 当主节点宕机时,协助从节点选举出新的主节点
# 注意: 仲裁节点不保存任何数据,资源消耗极低
# ============================================================
# ---------- 系统日志配置 ----------
systemLog:
# destination: 日志输出目标,file 表示输出到文件
destination: file
# path: 日志文件的完整路径
path: "/usr/local/mongodb/log/standalone/mongodb.log"
# logAppend: true 表示每次重启时追加到现有日志文件末尾,而非覆盖
logAppend: true
# ---------- 存储配置 ----------
storage:
# dbPath: MongoDB 数据文件存储目录
# 注意: 仲裁节点虽然不存储实际数据,但仍需要此目录存放一些元数据
dbPath: "/usr/local/mongodb/data/standalone"
# ---------- 进程管理配置 ----------
processManagement:
# fork: true 表示以后台守护进程方式运行(后台运行)
fork: true
# pidFilePath: 保存进程ID(PID)的文件路径,用于管理进程
pidFilePath: "/usr/local/mongodb/conf/mongod.pid"
# ---------- 网络配置 ----------
net:
# bindIp: 绑定监听的IP地址
# 0.0.0.0 表示监听所有网络接口(允许任何IP连接)
# 生产环境建议改为具体IP,如 192.168.7.100
bindIp: 0.0.0.0
# port: MongoDB 服务监听的端口号,默认 27017
port: 27017
# ---------- 副本集配置 ----------
replication:
# replSetName: 副本集名称,三台服务器必须保持一致
# 这里命名为 rs0(replica set 0 的缩写)
replSetName: rs0三台机器分别启动 MongoDB
mongod -f /usr/local/mongodb/conf/standalone/mongodb.conf仅在主节点(192.168.7.101) 初始化副本集
# 连接客户端
mongosh 192.168.7.101:27017
# 初始化设置
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "192.168.7.101:27017" },
{ _id: 1, host: "192.168.7.102:27017" },
{ _id: 2, host: "192.168.7.100:27017", arbiterOnly: true }
]
})
# 验证集群状态的两个指令
rs.conf();
rs.status()
数据同步测试
# 连接主节点执行
mongosh 192.168.7.101:27017
# 执行操作
use testDB
db.testCollection.insertOne({ name: "测试数据", createTime: new Date() })
db.testCollection.find()
# 连接从节点执行
mongosh 192.168.7.102:27017
# 开启从节点读权限
rs.setReadPref("primaryPreferred")
# 执行操作
use testDB
db.testCollection.find()再来连接仲裁节点看看情况
# 连接仲裁节点
mongosh 192.168.7.100:27017
# 测试仲裁节点
use testDB
db.testCollection.find()
MongoServerError: node is not in primary or recovering state
提示:"当前节点既不是主节点,也不是正在恢复中的从节点,所以无法执行操作。"外部连接操作
为了外部可以连接,需要开放MongoDB端口、更新防火墙(关闭防火墙也行):
# 在 public 区域添加规则:永久开放 TCP 端口 27017
firewall-cmd --zone=public --add-port=27017/tcp --permanent
# 重新加载防火墙配置,使新规则立即生效
firewall-cmd --reload
# 列出 public 区域当前所有已开放的端口
firewall-cmd --zone=public --list-ports副本集群主从切换
# 查询mongodb进程
ps aux | grep mongodb
# 在主节点模拟宕机(强杀主节点)
kill -9 xxxx
# 等待几秒钟,去从节点查看
rs.status();
'信息查询解释(主)'
{
_id: 0,
name: '192.168.7.101:27017',
health: 0, // ❌ 不健康
stateStr: '(not reachable/healthy)',
lastHeartbeatMessage: 'Error connecting to 192.168.7.101:27017 :: caused by :: Connection refused'
}
'信息查询解释(从)'
{
_id: 1,
name: '192.168.7.102:27017',
health: 1, // ✅ 健康
stateStr: 'PRIMARY', // ✅ 已成为新主节点
self: true // 当前连接的节点
}
'信息查询解释(仲裁)'
{
_id: 2,
name: '192.168.7.100:27017',
health: 1, // ✅ 健康
stateStr: 'ARBITER' // 仲裁角色不变
}
# 重启主节点
mongod -f /usr/local/mongodb/conf/standalone/mongodb.conf
# 等待几秒钟从节点继续查看状态
rs.status();
'信息查询解释(主)'
{
_id: 0,
name: '192.168.7.101:27017',
health: 1, // ✅ 已恢复健康
stateStr: 'SECONDARY', // 🔄 降级为从节点
syncSourceHost: '192.168.7.102:27017', // 📥 从新主节点同步数据
uptime: 21 // 刚重启 21 秒
}
'信息查询解释(从)'
{
_id: 1,
name: '192.168.7.102:27017',
health: 1,
stateStr: 'PRIMARY', // 👑 继续担任主节点
self: true // 当前连接的节点
}
'信息查询解释(仲裁)'
{
_id: 2,
name: '192.168.7.100:27017',
health: 1,
stateStr: 'ARBITER' // 仲裁角色不变
}
# 将主、从节点都干掉,再在仲裁节点上观察集群的状态
rs.status();
# 当前集群状态
节点 IP:端口 角色 状态 健康度
主节点 192.168.7.102:27017 ~~PRIMARY~~ ❌ 已宕机 health: 0
从节点 192.168.7.101:27017 ~~SECONDARY~~ ❌ 已宕机 health: 0
仲裁节点 192.168.7.100:27017 ARBITER ✅ 正常运行 health: 1
副本集状态诊断
# 基础状态查看
rs.status() // 副本集完整状态(最常用)
rs.conf() // 副本集配置信息
rs.isMaster() // 当前节点角色信息(快速判断主从)
原创
MongoDB搭建集群(高可用)
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法