认识
一、认识
MongoDB
复制(Replication
) 是通过 副本集(Replica Set
) 提供数据冗余和高可用性的一种机制。
MongoDB
复制(Replication
)优势: 高可用性, 即使主节点故障,副本集仍可自动选举新的主节点; 数据冗余, 多个副本保证数据不会轻易丢失; 读写分离,提升性能, 读请求可以被分发到多个从节点,提高读取吞吐量, 相比传统数据库的主从复制,支持自动选主和更灵活的读写分离。支持故障转移, 发生故障时,副本集能自动选举新的主节点,快速恢复服务,减少运维工作量。
MongoDB
复制(Replication
)架构: 副本集通常由 1
个主节点 和 多个从节点 组成。当主节点发生故障, 副本集会自动选举新的主节点,确保 MongoDB
集群的高可用性。副本集 是一组 MongoDB
实例, 包括: 主节点(Primary
), 负责接收写入请求, 所有写入请求都在此处理,并同步到从节点; 从节点(Secondary
), 从主节点复制数据,提供高可用性; 仲裁节点(Arbiter
,可选), 不存储数据,仅参与选举,用于维持奇数投票节点,保证选举稳定性, 帮助确定新的主节点。
[Primary]
│
┌────┴──────┐
[Secondary] [Secondary]
│
[Arbiter] (可选)
MongoDB
复制(Replication
)工作:
-
主节点(
Primary
)处理写入请求: 所有写入请求都在此处理,并同步到从节点。客户端将数据写入主节点, 主节点将操作日志(oplog
)存入local.oplog.rs
集合。oplog
(操作日志) 存储在local.oplog.rs
集合中,是一个Capped Collection
(固定大小集合),记录所有写操作(insert
、update
、delete
)。超过oplog
大小限制的日志 会被自动清理(默认oplogSize
), 如果Secondary
复制太慢,oplog
超过限制,数据同步会中断! -
从节点(
Secondary
)异步复制数据: 从节点周期性拉取主节点的oplog
并按顺序重放主节点的操作, 进行异步同步, 数据最终保持一致。同步成功后,Secondary
提交ACK
确认, 让Primary
维护同步进度。但存在一定的 复制延迟, 由于复制是异步的, 从节点数据可能落后于主节点, 导致数据最终一致,导致读写不一致。默认情况下,MongoDB
不等待Secondary
复制完成, 可以使用majority
(多数派)策略,确保数据写入多个节点, 通过writeConcern
进行同步复制, 所有写操作都要等待多数副本确认后才返回成功, 提供强一致性,但写入性能较低。db.collection.insertOne({ name: "Alice" }, { writeConcern: { w: "majority" } });
只有大多数节点(
>50%
)确认写入后,才返回成功。提高数据可靠性,但增加写入延迟。 -
故障转移(
Failover
)机制: 当主节点在超过配置的electionTimeoutMillis
时间段(默认10
秒)内未与副本集中的其他节点通信时,一个符合条件的从节点将发起选举,并提名自己成为新的主节点。集群将尝试完成新主节点的选举并恢复其正常运转。选举机制使用Raft
算法,基于心跳检测和oplog
追踪。当主节点失效时,MongoDB
自动选举新的主节点:-
节点健康检查(心跳检测): 当主节点在超过配置的
electionTimeoutMillis
时间段(默认10
秒)内未与副本集中的其他节点通信时,一个符合条件的从节点将发起选举,并提名自己成为新的主节点。 -
投票选举(多数派原则,投票数 >
50%
):MongoDB
选举基于Raft
一致性算法, 选举流程: 1. 候选状态(Candidate
), 一个Secondary
发起选举,广播RequestVote
请求,争取其他Secondary
支持; 2. 投票阶段, 需要超过50%
以上节点投票才能当选Primary
; 3.Primary
当选, 获胜节点成为新的Primary
,并接管所有写入请求。补充: 如果副本集成员为偶数时, 仲裁节点(Arbiter
)维持奇数投票数,防止投票僵持。
-
MongoDB
复制(Replication
)优化:
-
复制延迟优化:
-
增加
oplog
大小:oplog
默认大小可能不够,可以增大,db.adminCommand({ replSetResizeOplog: 1, size: 10240 }) // 10GB
。超过oplog
大小限制的日志会被自动清理(默认oplogSize
), 如果Secondary
复制太慢, 复制速度跟不上,oplog
超过限制,数据同步会中断! -
启用
w: majority
写入策略: 默认情况下,MongoDB
不等待Secondary
复制完成, 可以使用majority
(多数派)策略,确保数据写入多个节点, 通过writeConcern
进行同步复制, 所有写操作都要等待多数副本确认后才返回成功, 提供强一致性,但写入性能较低。db.collection.insertOne({ name: "Alice" }, { writeConcern: { w: "majority" } });
只有大多数节点(
>50%
)确认写入后,才返回成功。提高数据可靠性,但增加写入延迟。 -
调整
Secondary
读取优先级:rs.secondaryOk();
-
减少
Secondary
复制延迟: 调整secondaryDelaySecs
, 减少Secondary
同步间隔 -
降低
Secondary
复制时的CPU
限制:mongod --replSet rs0 --oplogSize 20480
-
-
读写分离: 副本集读策略, 在副本集中,默认所有的写请求都在主节点进行,而读请求可以由主节点或从节点处理。
MongoDB
提供不同的读取优先级。默认所有查询都在Primary
上进行,可能导致主节点压力过大, 优化方案, 将部分查询重定向到Secondary
,提升读性能。可在应用层通过 读偏好(Read Preference
) 让部分查询走从节点:db.collection.find().readPref("secondaryPreferred");
。MongoDB
读取策略:-
primary
(默认):只从主节点读取(强一致性)。 -
primaryPreferred
:优先从主节点读取,主节点不可用时从从节点读取。 -
secondary
:只从从节点读取(读性能高,但可能数据有延迟)。 -
secondaryPreferred
:优先从从节点读取,所有从节点不可用时才从主节点读取。 -
nearest
:从最接近的节点读取(无论主从)。
-
-
复制速度优化:
-
增大从节点的
oplog
读取线程:mongod --replSet rs0 --oplogSize 10240
-
从节点启用
readPref("nearest")
,减少读延迟
-