对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

复制

MongoDB 中的副本集是一组维护相同数据集的 mongod 进程。副本集提供冗余和高可用性,是所有生产部署的基础。本节将介绍 MongoDB 中的副本以及副本集的组件和架构。本节还提供了与副本集相关的常见任务教程。

复制提供冗余和数据可用性,在数据库服务器上维护多个数据副本,以容忍任何单个服务器的丢失。

在某些情况下,复制可以提供更多的读取容量,因为客户端可以将读取请求发送到不同的服务器。在不同数据中心维护数据副本可以提高分布式应用程序的数据局部性和可用性。您还可以根据特定目的维护额外的副本,如灾难恢复、报告或备份。

副本集是一组维护相同数据集的 mongod 实例。副本集包含多个数据承载节点和一个可选的仲裁节点。在数据承载节点中,只有一个主节点,其他被为从节点。

警告

每个副本集节点必须属于且只属于一个副本集。副本集节点不能属于多个副本集。

主节点会接收所有写入操作。副本集只能有一个可以使用 { w: "majority" } 写关注 (write concern) 级别对写入请求进行确认的主节点;尽管在某些情况下,另一 mongod 实例可能会暂时将自身视为主节点。[1] 主节点在其操作日志(即 oplog)中记录对其数据集的所有更改。有关主节点操作的更多信息,请参阅副本集主节点

读取和写入主节点的默认路由示意图。
点击放大

从节点复制主节点的 oplog,并将这些操作应用于其数据集,以便从节点的数据集反映主节点的数据集状态。如果主节点不可用,则某个符合条件的从节点将进行选举,以将自己选举为新的主节点。有关从节点的更多信息,请参阅副本集从节点

由一个主节点和两个从节点组成的 3 节点副本集的示意图。

如果费用限制阻止添加另一个从节点,您可以将一个 mongod 实例作为仲裁节点添加到副本集中。仲裁节点参与选举,但不持有数据(即不提供数据冗余)。有关仲裁节点的更多信息,请参阅副本集仲裁节点

由一个主节点、一个从节点和一个仲裁节点组成的副本集示意图。

仲裁节点永远是仲裁节点,而在选举期间,主节点可能被降级成为从节点,从节点可能变为主节点。

从节点会复制主节点的 oplog 并将操作异步应用于其数据集。通过使从节点的数据集反应主节点数据集的状态,即便一个或多个节点出现故障,副本集也可继续运行。

有关复制机制的更多信息,请参阅副本集 Oplog副本集数据同步

现在,副本集的从节点会记录应用时间超过慢操作阈值的 oplog 条目。这些慢 oplog 消息:

  • diagnostic log中针对从节点记录。

  • 记录在 REPL 组件下,该组件将含有文本 applied op: <oplog entry> took <num>ms

  • 不依赖日志级别(系统级别或组件级别)

  • 不依赖于分析级别。

  • slowOpSampleRate 影响。

分析器不会捕获慢 oplog 条目。

复制延迟是指主节点上的操作与将该操作从 oplog 应用到从节点之间的延迟。一些小的延迟是可以接受的,但随着复制延迟的增加,会出现严重的问题,包括在主节点上创建缓存压力。

从 MongoDB 4.2 开始,管理员可以限制主节点应用写入的速率,目标是将 majority committed 延迟保持在可配置的最大 flowControlTargetLagSeconds 值以下。

默认情况下,流量控制为 enabled

启用流量控制后,随着延迟接近 flowControlTargetLagSeconds,主节点上的写入操作必须先获取票据,然后才能获取锁以应用写入操作。通过限制每秒发出的票据数量,流量控制机制将尝试将延迟保持在目标延迟以下。

有关更多信息,请参阅检查复制延迟流控制

当主节点在超过配置的 electionTimeoutMillis 时间段(默认 10 秒)内未与副本集中的其他节点通信时,符合条件的从节点将要求进行选举以将自己指定为新的主节点。

在主节点变得无法访问后,在三节点副本集中进行选举。
点击放大

The median time before a cluster elects a new primary should not typically exceed 12 seconds, assuming default replica configuration settings. This includes time required to mark the primary as unavailable and call and complete an election. You can tune this time period by modifying the settings.electionTimeoutMillis replication configuration option. Factors such as network latency may extend the time required for replica set elections to complete, which in turn affects the amount of time your cluster may operate without a primary. These factors are dependent on your particular cluster architecture.

electionTimeoutMillis 复制配置选项从默认的 10000(10 秒)降低,可以更快地检测到主节点故障。然而,由于临时网络延迟等因素,即使主节点在其他方面是健康的,集群也可能会更频繁地进行选举。这可能导致 w: 1 写入操作的回滚次数增加

您的应用程序连接逻辑应包括对自动故障转移和后续选举的容忍度。MongoDB 驱动程序可检测到主节点丢失,并一次性自动重试某些写入操作,从而为自动故障转移和选举提供额外的内置处理功能:

兼容的驱动程序将默认启用可重试写入

MongoDB provides mirrored reads to pre-warm electable secondary members' cache with the most recently accessed data. Pre-warming the cache of a secondary can help restore performance more quickly after an election.

要了解有关 MongoDB 故障转移过程的更多信息,请参阅:

默认情况下,客户端从主节点 [1] 读取;但是,客户端可以指定读取偏好以向从节点发送读取操作。

使用读取偏好为从节点的应用程序示意图。
点击放大

异步复制到从节点意味着在从节点读取到的数据可能不会反映主节点上数据的状态。

包含读取操作的事务必须使用读取偏好(read preference)primary。给定ACID 事务中的所有操作必须路由到同一成员。

有关从副本集读取的信息,请参阅读取偏好。

根据读关注,客户端可在写入操作持久化之前看到写入结果:

  • 无论写入操作的写关注级别如何,使用 "local""available" 读关注(read concern)的其他客户端均可在写入操作被发起它的客户端确认之前,看到该操作的结果。

  • 使用 "local""available" 读关注的客户端可读取数据,而这些数据后续可能会在副本集故障转移期间进行回滚

对于多文档事务中的操作,当事务提交时,该事务中进行的所有数据更改都将保存并在事务外部可见。换言之,一个事务不会在回滚其他事务的同时提交某些更改。

在事务进行提交前,在事务中所做的数据更改在事务外不可见。

不过,当事务写入多个分片时,并非所有外部读取操作都需等待已提交事务的结果在各个分片上可见。例如,如果事务已提交并且写入 1 在分片 A 上可见,但写入 2 在分片 B 上尚不可见,则读关注 "local" 处的外部读取可以在不看到写入 2 的情况下读取写入 1 的结果。

有关 MongoDB 读取隔离性、一致性和新近度的更多信息,请参阅读取隔离性、一致性和新近度

镜像读通过在发生故障转移之前预热 electable 从节点副本集成员的缓存,从而减少主节点选举的影响。主节点会将其接收到的一部分受支持的操作镜像到可选举的从节点上。

可以使用 mirrorReads 参数来配置接收镜像读的 electable 从节点副本集节点的子集的大小。有关更多详细信息,请参见启用/禁用对镜像读的支持

注意

镜像读取不会影响主节点对客户端的响应。主节点镜像复制到从节点的读取是“发后即忘”类型的操作。主节点不会等待响应。

镜像读取支持以下操作:

  • findAndModify (具体来说,过滤器将作为一次镜像读取请求发送)

  • update (具体来说,过滤器将作为一次镜像读取请求发送)

默认情况下启用镜像读并使用默认的 sampling rate(值为 0.01)。要禁用镜像读,请将 mirrorReads 参数设置为 { samplingRate: 0.0 }

db.adminCommand( {
setParameter: 1,
mirrorReads: { samplingRate: 0.0 }
} )

With a sampling rate greater than 0.0, the primary mirrors supported reads to a subset of electable secondaries. With a sampling rate of 0.01, the primary mirrors one percent of the supported reads it receives to a selection of electable secondaries.

例如,考虑一个副本集,其由一个主节点和两个可选的辅助节点组成。如果主节点接收到 1000 个可镜像的操作,且采样率为 0.01,则主节点会将大约 10 次支持读镜像到随机选择的可选辅助节点。

要更改镜像读取的采样率,请将 mirrorReads 参数设为 0.01.0 之间的数字:

  • 采样率设置为 0.0 将禁用镜像读。

  • 采样率介于 0.01.0 之间时,主节点会以指定的采样率向可参选从节点随机转发支持的读取操作

  • 采样率 1.0 会导致主节点将所有支持的读取操作转发到可参选从节点。

有关详细信息,请参阅mirrorReads

如果您在下列操作中指定以下字段,serverStatus 命令和 db.serverStatus() Shell 方法会返回 mirroredReads 指标:

db.serverStatus( { mirroredReads: 1 } )

从 MongoDB 4.0 开始,多文档事务对副本集可用。

包含读取操作的事务必须使用读取偏好(read preference)primary。给定ACID 事务中的所有操作必须路由到同一成员。

在事务进行提交前,在事务中所做的数据更改在事务外不可见。

不过,当事务写入多个分片时,并非所有外部读取操作都需等待已提交事务的结果在各个分片上可见。例如,如果事务已提交并且写入 1 在分片 A 上可见,但写入 2 在分片 B 上尚不可见,则读关注 "local" 处的外部读取可以在不看到写入 2 的情况下读取写入 1 的结果。

从 MongoDB 3.6 开始,变更流 可用于副本集和分片集群。变更流允许应用程序访问实时数据变化,而无需实时跟踪 oplog ,这可能相当复杂且容易出错。应用程序可以使用变更流来订阅一个或多个集合上的所有数据变更。

副本集可提供多个选项来支持应用程序需求。例如,您可以部署一个副本集,而其节点位于多个数据中心,或是通过调整某些节点的 members[n].priority 来控制选举结果。副本集还支持用于报告、灾难恢复或备份功能的专门节点。

请参阅优先级为 0 的副本集节点隐藏副本集节点延时副本集节点,以了解更多信息。

[1](1, 2)

某些情况下,副本集中的两个节点可能会暂时认为它们是主节点,但最多只能有其中一个节点能够完成具有{ w: "majority" }写入关注的写入操作。可以完成{ w: "majority" }写入操作的节点是当前主节点,另一个节点是尚未识别其降级(通常是由于网络分区)的前主节点。发生这种情况时,尽管已请求读取偏好primary,但连接到前主节点的客户端可能会观察到过时数据,并且对前主节点的新写入操作最终将回滚。