MongoDB 复制(副本集)
MongoDB 复制(Replication) 通过 副本集(Replica Set) 机制,确保数据高可用性,提高故障恢复能力,防止单点故障。
1. 什么是副本集(Replica Set)?
副本集是 一组 MongoDB 服务器节点,其中:
- 一个 作为 主节点(Primary),负责写入和读取。
- 多个 作为 从节点(Secondary),负责数据同步和备份。
- 可选 仲裁节点(Arbiter),仅用于选举,不存储数据。
基本架构:
+----------------+
| Client |
+----------------+
|
v
+-----------------+
| Primary (Master) |
+-----------------+
|
v
+-----------------+ +-----------------+
| Secondary 1 | ← | Secondary 2 |
+-----------------+ +-----------------+
|
v
+-----------------+
| Arbiter (可选) |
+-----------------+
2. 副本集的优点
✅ 高可用性:主节点故障时,从节点可自动提升为主节点。
✅ 数据冗余:多台服务器存储相同数据,防止数据丢失。
✅ 负载均衡:查询可在多个从节点上执行,提高读取性能。
✅ 故障自动恢复:MongoDB 自动选举新的主节点,无需人工干预。
3. 配置副本集
(1)准备服务器
至少三台 MongoDB 服务器:
Primary(主节点)Secondary(从节点)Arbiter(仲裁节点,非必须)
(2)启动 MongoDB 副本集
启动副本集模式,每台服务器执行:
mongod --replSet myReplicaSet --port 27017 --dbpath /data/db --bind_ip 0.0.0.0
--replSet myReplicaSet:指定副本集名称(所有节点必须相同)。--port 27017:指定端口。--dbpath /data/db:指定数据目录。
(3)初始化副本集
在 主节点 上执行:
rs.initiate({
_id: "myReplicaSet",
members: [
{ _id: 0, host: "192.168.1.1:27017" },
{ _id: 1, host: "192.168.1.2:27017" },
{ _id: 2, host: "192.168.1.3:27017", arbiterOnly: true } // 仲裁节点
]
})
_id:节点编号。host:MongoDB 服务器 IP 和端口。arbiterOnly: true:指定为仲裁节点。
(4)查看副本集状态
rs.status()
如果正常运行,会看到:
{
"set": "myReplicaSet",
"members": [
{ "stateStr": "PRIMARY", "name": "192.168.1.1:27017" },
{ "stateStr": "SECONDARY", "name": "192.168.1.2:27017" },
{ "stateStr": "ARBITER", "name": "192.168.1.3:27017" }
]
}
4. 读写操作
(1)默认写入规则
所有写操作只能在 Primary(主节点) 上进行:
db.users.insertOne({ name: "Alice", age: 25 });
(2)默认读取规则
默认所有查询也在 主节点 执行:
db.users.find();
要从 Secondary 读取数据(只读),需执行:
db.getMongo().setReadPref("secondary");
db.users.find();
(3)读优先级(Read Preference)
MongoDB 提供多种读取策略:
| 模式 | 说明 |
|---|---|
primary | 只从主节点读取(默认) |
primaryPreferred | 优先从主节点读取,主节点不可用时,从从节点读取 |
secondary | 只从从节点读取 |
secondaryPreferred | 优先从从节点读取,所有从节点不可用时,从主节点读取 |
nearest | 选择延迟最小的节点(主从皆可) |
示例:
db.getMongo().setReadPref("secondaryPreferred");
5. 故障切换(自动选举)
(1)Primary 宕机
如果 主节点故障,MongoDB 自动选举新的主节点:
- 从 存活的从节点 选举票数最高的作为新的 Primary。
- 其他从节点继续作为 Secondary。
- 原 Primary 恢复后,降级为 Secondary。
(2)手动强制选举
如果要手动提升某个节点为 Primary:
rs.stepDown();
然后在新的主节点上执行:
rs.reconfig({
_id: "myReplicaSet",
members: [
{ _id: 0, host: "192.168.1.1:27017", priority: 0 },
{ _id: 1, host: "192.168.1.2:27017", priority: 2 }, // 提高优先级
{ _id: 2, host: "192.168.1.3:27017", arbiterOnly: true }
]
})
priority: 2→ 提高优先级,使该节点优先当选。
6. 延迟副本(Hidden Replica)
有些从节点仅用于备份,不希望客户端读取:
rs.reconfig({
_id: "myReplicaSet",
members: [
{ _id: 0, host: "192.168.1.1:27017" },
{ _id: 1, host: "192.168.1.2:27017" },
{ _id: 2, host: "192.168.1.3:27017", hidden: true, priority: 0 }
]
})
hidden: true→ 该节点不被发现,不能被读取。priority: 0→ 不能成为 Primary。
7. 备份与恢复
(1)备份数据
使用 mongodump 备份:
mongodump --host 192.168.1.1 --out /backup/mongo/
(2)恢复数据
使用 mongorestore 恢复:
mongorestore --host 192.168.1.2 --dir /backup/mongo/
8. 总结
| 功能 | 说明 |
|---|---|
| 主节点(Primary) | 负责所有写入,默认也处理读取 |
| 从节点(Secondary) | 复制主节点数据,可用于只读查询 |
| 仲裁节点(Arbiter) | 仅用于投票,不存储数据 |
| 自动故障转移 | 主节点故障时,MongoDB 自动选举新主节点 |
| 读优先级 | 允许主从混合查询(primaryPreferred、secondaryPreferred 等) |
| 隐藏副本 | 防止从节点被读取(hidden: true) |
| 手动选举 | 通过 rs.stepDown() 或 priority 控制 |
MongoDB 复制 提供了高可用性、数据冗余、自动故障恢复,是分布式架构的基础! 更多详细内容请关注其他相关文章!