MongoDB 复制集(Replica Set)由一组 mongod 实例组成,提供数据冗余和高可用性。本文深入复制集的原理、配置和运维实践。
1. 复制集架构
┌─────────────────┐
│ Primary │ ← 唯一可写,所有写操作通过这里
│ (priority:1) │
└────────┬────────┘
│ 写入
┌────────┴────────┐
│ │
┌───────▼───────┐ ┌────▼──────────┐
│ Secondary 1 │ │ Secondary 2 │ ← 只读,异步复制 oplog
│(priority:0.5) │ │(priority:0.5) │
└───────────────┘ └───────────────┘
可选: Arbiter(仲裁节点,无数据,只参与选举)
复制集规则:
- Primary 宕机后,Secondary 选举产生新 Primary
- 多数节点存活则可选举(N/2 + 1)
- 写操作默认确认到 Primary 即返回(可调整 writeConcern)
2. 部署配置
2.1 初始化复制集
// 连接到 mongo shell
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo1:27017", priority: 2 },
{ _id: 1, host: "mongo2:27017", priority: 1 },
{ _id: 2, host: "mongo3:27017", priority: 1, arbiterOnly: false }
]
});
// 查看状态
rs.status();
rs.conf();
2.2 读写分离
// 连接串
mongodb://user:pass@mongo1:27017,mongo2:27017,mongo3:27017/mydb?replicaSet=rs0&readPreference=secondaryPreferred
// readPreference 选项:
// primary → 只读主库(默认)
// primaryPreferred → 优先主库,主库不可用时读从库
// secondary → 只读从库
// secondaryPreferred → 优先从库
// nearest → 读网络延迟最低的节点
2.3 Write Concern
// 写入确认级别
db.products.insertOne(doc, {
writeConcern: {
w: "majority", // 大多数节点确认
j: true, // 写入 journal
wtimeout: 5000 // 超时 5 秒
}
});
// w 选项:
// 0 → 不等待确认(最快,可能丢数据)
// 1 → Primary 确认(默认)
// majority → 大多数节点确认
// n → n 个节点确认
3. 故障转移
正常状态:
Primary ←─同步─→ Secondary 1
│
└─────────────→ Secondary 2
故障场景: Primary 宕机
↓ 心跳检测超时(默认 10s)
Secondary 1 & 2 发起选举
↓ 优先级较高者成为新 Primary
Secondary 1 提升为 Primary
原 Primary 恢复后 → 作为 Secondary 加入
脑裂防护:旧 Primary 如果在网络分区后仍认为自己有效——此时新 Primary 已被选举出来,旧 Primary 发现自己不再是多数派后自动降级为 Secondary。
4. oplog 机制
// oplog(操作日志)是 capped collection,记录所有写操作
rs.printReplicationInfo(); // oplog 大小和窗口
rs.printSlaveReplicationInfo(); // 各节点同步延迟
// oplog 大小计算: 足够容纳一次完整同步的时间
// 默认: 磁盘空间的 5%
5. 生产部署建议
| 建议 | 说明 |
|---|---|
| 最少 3 节点 | 容忍 1 节点故障 |
| 奇数节点 | 避免选举僵局 |
| 跨可用区 | 机房级容灾 |
| 优先使用 Hidden/Secondary | 报表/备份任务不干扰主库 |
| 监控 lag | Secondary 延迟超过阈值告警 |
延伸阅读
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。