Docs 菜单

Docs 主页开发应用程序MongoDB Manual

复制

在此页面上

  • 冗余和数据可用性
  • MongoDB 中的复制
  • 异步复制
  • 自动故障转移
  • 读取操作
  • 事务
  • Change Streams
  • 其他功能

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

对于 MongoDB Atlas 中托管的部署,您可以在用户界面中 部署副本集 。

复制可提供冗余并提高数据可用性。通过在不同的数据库服务器上设置数据副本,复制为单个数据库服务器丢失的情况提供了一定程度的容错能力。

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

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

警告

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

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

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

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

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

在某些情况下(例如存在一个主节点和一个从节点,但由于成本有限无法再添加另一个从节点),您可以选择将一个 mongod 实例作为仲裁节点添加到副本集中。仲裁节点参与选举,但不持有数据(即不提供数据冗余)。有关仲裁节点的更多信息,请参阅副本集仲裁节点

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

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

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

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

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

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

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

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

  • 不依赖于分析级别。

  • slowOpSampleRate的影响。

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

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

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

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

注意

要启用流量控制,副本集/分片集群必须具有: featureCompatibilityVersion (fCV)4.2 ,且读关注(read concern)为 majority enabled。也就是说,如果 fCV 不是 4.2 或读关注已被禁用,则已启用的流量控制将不会生效。

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

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

当主节点在超过配置的 electionTimeoutMillis 时间段(默认 10 秒)内未与副本集中的其他节点通信时,一个符合条件的从节点将发起选举,并提名自己成为新的主节点。集群将尝试完成新主节点的选举并恢复其正常运转。

新主节点选举示意图。在具有两个从节点的三节点副本集中,主节点会变得无法访问。主节点丢失会触发选举,其中一个从节点会成为新的主节点
点击放大

在成功完成选举之前,副本集无法处理写操作。如果将读取查询配置为当主节点离线时在从节点上运行,那么副本集可以继续为读取查询提供服务。

假设默认值为replica configuration settings ,集群选举新的主节点之前的平均时间通常不应超过12秒。这包括将主节点标记为不可用以及召集和完成选举所需的时间。您可以通过修改settings.electionTimeoutMillis复制配置选项来调整该时间段。网络延迟等因素可能会延长副本集选举完成所需的时间,从而影响集群在没有主节点的情况下运行的时间。这些因素取决于特定的集群架构。

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

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

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

MongoDB 提供镜像读,以使用最近访问的数据预热可选举从节点成员的缓存。预热从节点的缓存有助于在选举后更快地恢复性能。

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

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

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

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

包含读操作的分布式事务必须使用读取偏好 primary。给定事务中的所有操作必须路由至同一节点。

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

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

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

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

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

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

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

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

镜像读取可减少由于中断或计划维护后主节点选举对系统的影响。在副本集发生故障转移后,接管成为新主节点的从节点会在新查询请求传入时更新其缓存。在缓存预热期间,性能可能会受到影响。

镜像读会预热electable从节点副本集成员的缓存。为了预热可选举辅助节点的缓存,主节点会将其接收到的受支持操作的样本镜像到可选举辅助节点。

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

注意

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

镜像读取支持以下操作:

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

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

当采样率大于0.0时,主节点镜像支持读取electable个从节点的子集。采样率为0.01时,主节点会将其收到的受支持读取的 1% 镜像到一系列可选举的从节点。

例如,考虑一个副本集,其由一个主节点和两个可参选的从节点组成。如果主节点接收到 1000 个可镜像复制的操作,且采样率为 0.01,那么主节点会将大约 10 个受支持的读取操作镜像复制到可参选的从节点。每个可参选的从节点只接受 10 个读取请求中的一小部分。主节点将把每个镜像读取请求随机发送到非空的可参选从节点。

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

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

  • 采样率介于0.01.0之间会导致主节点以指定的采样率将支持读取的随机样本转发到可选举的辅助节点。

  • 采样率为1.0会导致主节点将所有支持的读取转发到可选举的辅助节点。

有关详细信息,请参阅mirrorReads

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

db.serverStatus( { mirroredReads: 1 } )

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

包含读操作的分布式事务必须使用读取偏好 primary。给定事务中的所有操作必须路由至同一节点。

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

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

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

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

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

[1](1, 2)某些情况下,副本集中的两个节点可能会暂时都认为自己是主节点,但最多只有一个节点能完成 { w: "majority" } 写关注的写入操作。能够完成 { w: "majority" } 写入操作的节点是当前的主节点,另一个节点是尚未意识到自己已降级(通常由于网络分区)的前主节点。发生这种情况时,即使已请求了读取偏好为 primary,连接到前主节点的客户端依然可能观察到过时的数据,并且对前主节点的新的写入操作最终将被回滚。
← 数据库引用