MongoDB 复制(副本集)
                           
天天向上
发布: 2025-03-07 23:00:27

原创
462 人浏览过

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 自动选举新的主节点:

  1. 存活的从节点 选举票数最高的作为新的 Primary。
  2. 其他从节点继续作为 Secondary。
  3. 原 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 自动选举新主节点
读优先级允许主从混合查询primaryPreferredsecondaryPreferred 等)
隐藏副本防止从节点被读取hidden: true
手动选举通过 rs.stepDown()priority 控制

MongoDB 复制 提供了高可用性、数据冗余、自动故障恢复,是分布式架构的基础! 更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *