最小MRE

# 启动复制集
mongod --replSet rs0 --port 27017 --dbpath /data/rs0-1 --bind_ip localhost --fork --logpath /data/rs0-1/mongod.log
mongod --replSet rs0 --port 27018 --dbpath /data/rs0-2 --bind_ip localhost --fork --logpath /data/rs0-2/mongod.log
mongod --replSet rs0 --port 27019 --dbpath /data/rs0-3 --bind_ip localhost --fork --logpath /data/rs0-3/mongod.log

# 初始化复制集
mongosh --port 27017
rs.initiate({ _id:"rs0", members:[
  {_id:0, host:"localhost:27017"},
  {_id:1, host:"localhost:27018"},
  {_id:2, host:"localhost:27019"}
]})

主从复制的问题

oplog存储在local数据库的oplog.$main集合中。oplog具有幂等性,无论执行几次其结果都是一致的。

oplog字段

  • ts: 操作时间戳
  • h: 操作的唯一标识
  • op: 操作类型(i/u/d/c/n)
  • ns: 操作针对的集合
  • o: 操作内容

注意:MongoDB 4.0版本之后不再支持主从复制。

复制集

什么是复制集

复制集是由一组拥有相同数据集的MongoDB实例组成的集群。复制集提供数据冗余备份,并在多个服务器上存储数据副本。

复制集优势

  1. 高可用性:自动故障转移
  2. 数据安全与灾难恢复:实时数据同步
  3. 读写分离:主节点处理写操作,备节点处理只读操作
  4. 运维优势:滚动升级、地理分布

架构原理

oplog日志结构

{
  "ts": Timestamp(1446011584, 2),
  "h": NumberLong("1687359108795812092"),
  "op": "i",
  "ns": "test.nosql",
  "o": { "_id": ObjectId(...), "name": "mongodb" }
}

心跳检测机制

  • 心跳频率:默认每2秒
  • 超时设置:默认10秒
  • 状态维护:每个节点维护状态映射表

选举机制

触发选举时机

  • 第一次初始化复制集
  • Secondary节点权重比Primary节点高
  • Secondary节点发现集群中没有Primary
  • Primary节点不能访问到大部分成员

速查卡

参数默认值说明
heartbeatIntervalMillis2000ms心跳频率
heartbeatTimeoutSecs10s心跳超时阈值
electionTimeoutMillis10000ms选举超时时间
最大成员数50复制集成员上限
最大投票权7有投票权的成员上限

检查命令

  • db.getReplicationInfo(): 查看oplog状态
  • rs.printSecondaryReplicationInfo(): 查看从节点复制状态
  • rs.status(): 查看复制集整体状态