MongoDB 副本集

200 阅读4分钟

本文基于 mongodb 官方文档,版本为 4.4。

一个副本集就是一组 mongod 进程,成员包括:

Primary

成员 primary 接收所有的写操作。

Secondaries

Secondaries 复制来自 primary 的所有操作来保持一个相同的数据集。Secondaries 可能有用于特殊用途配置文件的其他用途。secondaries 可能是 non-voting 和 priority 0。

Arbiter

参与 elections 但是不持有数据也不能成为 primary,一个 arbiter 拥有 1 票。

Members

副本集的 Primary 节点

MongoDB 将所有的 write operations 作用于 primary 节点,并将操作记录都在 primary 节点的 oplog。Secondary 成员复制 log 并将操作应用于各自的数据集。

读操作默认作用于 primary,但是副本集的所有成员都能接收读操作。

Diagram of default routing of reads and writes to the primary. — Enlarged

副本集的 Secondary 节点

Priority 0 的成员

一个优先级为 0 的成员不能成员 primary 节点也不能够触发选举。它们维护一个数据集的副本,可以接收读操作,也可以在选举中投票。

Diagram of a 3 member replica set distributed across two data centers. Replica set includes a priority 0 member.

Hidden 副本集成员

一个 hidden 成员维持着一个 primary 数组的副本,但是对于客户端应用来说是不可见的。Hidden 长远 priority 为 0,但是可以参与投票。Hidden 成员主要用来做备份。

Delayed 副本集成员

Delayed 成员的数据集反映了primary数据集较早或延迟的状态。优先级必须为0,且应该是隐藏成员。

Arbiter 成员

Oplog

副本集中的所有成员都有一份 oplog 的拷贝,在 local.oplog.rs 集合。oolog 记录了所有对数据进行修改的操作。

为了促进复制,所有成员都将 heartbeats(ping)发送给所有其他成员。任何 Secondary 成员都可以从任何其他成员导入条目。

每一个操作都是幂等的,即 oplog 中的操作无论是应用一次还是多次都会产生相同的结果。

oplog size

初次启动副本集时如果没有明确 oplog size 的话,MongoDB 会创建一个默认大小的 oplog。不同的操作系统默认大小不同。

从 MongoDB 4.4 开始,可以指定一个 oplog entry 的最短保留时限。mongod 仅在满足以下条件时会删掉一个 oplog entry:

  • oplog 已经达到最大的配置大小;
  • oplog entry 的存在时间已经超过了配置的保留时限。

默认情况下,MongoDB不会设置最小操作日志保留期限,而是会从最早的条目开始自动截断操作日志,以保持配置的最大操作日志大小。

Minimum Oplog Retention Period

MongoDB 从4.4版本开始,可以给一条 oplog entry 指定最小的保留的小时数。

要在启动 mongod 时配置 minimum oplog retention period,可以采用如下两种方式之一:

  • 在 mongod 的配置文件里添加 storage.oplogMinRetentionHours;
  • 通过命令行启动时,使用 --oplogMinRetentionHours 参数。

使用 replSetResizeOplog 来更新已经运行的 mongod 进程的 minimum oplog retention period。

Workloads that Might Require a Larger Oplog Size

对于与如下类似的情形,可以考虑创建一个比默认更大的 oplog。相反地,如果你的应用主要是运行 reads,仅有少部分的 write operations,可以采用一个更小的 oplog。

Updates to Multiple Documents at Once

为了确保幂等性,oplog 必须将多个更新转化为一个单独的操作。这会占用大量操作日志空间,而不会相应增加数据大小或磁盘使用量。

Deletions Equal the Same Amount of Data as Inserts

删除操作大概与插入操作一样多的时候,数据库的大小不会有显著变化,但是操作日志会很大。

Significant Number of In-Place(原地) Updates

存在大量对于既有数据的更新操作时。

Oplog Status

可以使用 rs.printReplicationInfo() 方法来查看 oplog 的状态(大小和操作的时间跨度)。

Replication Lag and Flow Control

在各种特殊情况,对 secondary 的 oplog 的更新可能会滞后于所期望的运行时间。对secondary 成员使用 db.getReplicationInfo() ,通过复制状态的输出来评估当前复制的状态并且确定是否有预期之外的复制延迟。

(下面有一部分关于 Flow Control 没看懂)