副本集数据同步
为了维护共享数据集的最新副本,副本集的从节点会从源节点同步或复制数据。 MongoDB 使用两种形式的数据同步:初始同步(使用完整数据集填充新成员)和复制(将持续更改应用于整个数据集)。
初始化同步(Resumable Initial Sync)
初始同步将所有数据从副本集的源成员复制到目标成员。 有关源节点选择标准的更多信息,请参阅初始同步源选择。
注意
在初始同步期间, MongoDB会截断目标节点上的oplog 。这种oplog截断可能会影响依赖oplog数据的进程,例如变更流。
您可以使用 initialSyncSourceReadPreference
参数指定首选初始同步源。该参数只能在启动 mongod
时指定。
从 MongoDB 5.2 开始,初始同步可以是逻辑同步或基于文件拷贝的同步。
逻辑初始同步流程
执行逻辑初始同步时,MongoDB 将:
克隆除本地数据库之外的所有数据库。要进行克隆,
mongod
会扫描每个源成员数据库中的每个集合,并将所有数据插入自己的这些集合副本中。在为每个集合复制文档时构建该集合的所有索引。
在数据复制过程中拉取新添加的 oplog 记录。确保目标成员在
local
数据库中有足够的磁盘空间,以便在此数据复制阶段期间临时存储这些 oplog 记录。将所有更改应用于数据集。
mongod
使用来自源节点的 oplog,更新其数据集以反映副本集的当前状态。
完成初始同步后,节点从 STARTUP2
转换到 SECONDARY
。
要执行初始同步,请参阅重新同步自我管理副本集的成员。
基于文件副本的初始同步
仅在 MongoDB Enterprise 中可用。
基于文件复制的初始同步通过复制并移动文件系统上的文件来运行初始同步过程。这种同步方法可能比逻辑初始同步更快。
重要
基于文件复制的初始同步可能会导致计数不准确
基于文件复制的初始同步完成后,如果运行 count()
方法而未使用查询谓词,返回的文档数可能不准确。
不带查询谓词的 count
方法如下所示:db.<collection>.count()
。
要了解详情,请参阅没有查询谓词的不准确计数。
启用基于文件副本的初始同步
要启用基于文件拷贝的初始同步,请在初始同步的目标节点上将 initialSyncMethod
参数设置为 fileCopyBased
。此参数只能在启动时设置。
行为
同步时,基于文件副本的初始同步会将目标成员的local
数据库替换为源成员的local
数据库。
限制
在基于文件副本的初始同步期间:
不能在源节点或目标节点上运行备份。
您无法写入目标节点上的
local
数据库。
您一次只能从一个源成员运行初始同步。
使用加密存储引擎时,MongoDB 使用源节点密钥来加密目标节点。
NVMe 集群上的初始同步
您必须在使用本地非易失性内存高速 ( NVMe ) SSD 存储选项的集群上执行初始同步,如果您正在使用 Atlas自动伸缩,则包括在内。当90 % 的存储空间已满时,Atlas NVMe 集群会自动扩展到下一更高层级。与后续同步相比,初始同步需要更长的时间才能完成,并且会降低从中读取数据的主节点的性能。
容错
如果执行初始同步的目标成员在同步过程中遇到持续的网络错误,则目标成员会从头开始重新启动初始同步过程。
如果因临时网络错误、集合删除或集合重命名而中断,执行初始同步的目标节点可以尝试恢复同步过程。
默认情况下,目标成员会尝试在24小时内恢复初始同步。您可以使用initialSyncTransientErrorRetryPeriodSeconds
服务器参数来控制目标成员尝试恢复初始同步的时间。如果目标成员无法在配置的时间段内成功恢复初始同步过程,则会从副本集中选择一个新的健康源成员,并从头开始重新启动初始同步过程。
在返回致命错误之前,从节点会尝试重新启动初始同步最多 10
次。
初始同步源选择
初始同步源的选择取决于 mongod
启动参数 initialSyncSourceReadPreference
的值:
initialSyncSourceReadPreference
对于设置为 的primary
}(禁用chainingAllowed
时的默认值),请选择 主节点 作为源成员。如果主节点不可用或无法访问,请记录错误并定期检查主节点的可用性。如果
initialSyncSourceReadPreference
设置为primaryPreferred
(投票副本集成员的默认值),请尝试选择主节点作为源成员。如果主节点不可用或无法访问,则从其余副本集节点中选择同步源节点。对于所有其他受支持的读取模式,请从目标节点中执行同步源节点选择。
执行初始源节点选择的节点会对所有副本集节点的列表进行两次遍历:
在第一次选择初始源节点时,节点将以下条件应用于每个副本集节点:
源成员必须在线且可访问。
如果
initialSyncSourceReadPreference
为secondary
或secondaryPreferred
,则源成员必须是从节点。源成员必须是
visible
。源节点必须 在主节点上最新 oplog 条目的
30
秒之内。如果成员
builds indexes
,则源成员必须构建索引。如果副本集内的节点
votes
进行选举,则源节点也必须投票。如果该成员不是
delayed member
,则不得延迟源成员。如果成员是
delayed member
,则源成员必须配置更短的延迟。源成员必须比当前最佳同步源更快。
如果在第一次遍历后没有留下候选源成员,则该成员会使用宽松的标准执行第二次遍历。请参阅 Sync Source Selection (Second Pass) 。
在第二轮选择初始源节点时,该节点对每个副本集节点应用以下条件:
源成员必须在线且可访问。
如果
initialSyncSourceReadPreference
为secondary
,则源成员必须是从节点。如果成员
builds indexes
,则源成员必须构建索引。源成员必须比当前最佳同步源更快。
如果目标节点在两次遍历后无法选择源节点,则会记录错误并等待 1
秒,然后重新启动选择过程。从节点 mongod
可以最多重新启动 10
次初始同步源选择过程,然后退出并报告错误。
Oplog Window
oplog window 必须足够长,以便目标成员可以获取 逻辑初始同步过程 开始和结束之间出现的任何新 oplog 条目。如果窗口时间不够长,则存在以下风险:某些条目可能在目标成员应用之前脱离oplog
。
建议调整 oplog
的大小,以便有更多时间来获取所有新的 oplog
条目。此操作支持在初始同步期间可能出现的更改。
有关更多信息,请参阅 Oplog 大小。
复制
目标成员在初始同步后持续复制数据。目标成员从源成员复制oplog ,并在异步过程中应用这些操作。
目标成员会根据 ping 时间和其他成员复制状态的变化,按需自动更改源成员。有关源节点选择标准的更多信息,请参阅复制同步源选择。
流复制 (Streaming Replication)
源成员向目标成员发送连续的oplog条目流。流复制可缓解高负载和高延迟网络中的复制延迟。它还:
降低从从节点读取数据的陈旧度。
使用 w: 1 降低由于主节点故障转移而丢失写入操作的风险。
用
w: "majority"
和 w: >1(即任何需要等待复制的写关注)减少写入操作延迟。
使用oplogFetcherUsesExhaust
启动参数禁用流复制并使用较早的复制行为。仅当源成员有任何资源限制或者您希望限制 MongoDB 在复制时使用的网络带宽时,才将oplogFetcherUsesExhaust
参数设置为false
。
多线程复制
MongoDB 使用多个线程分批应用写操作,从而提高并发性。MongoDB 会按文档 ID (WiredTiger) 对批处理进行分组,并使用不同的线程同时应用每组操作。MongoDB 始终按按原始写入顺序向给定文档应用写入操作。
如果读取操作出现在应用复制批处理的从节点上,则定位于从节点且配置有读关注级别为 "local"
或 "majority"
的读取操作将从该数据的 WiredTiger 快照进行读取。
从快照中读取可保证数据视图的一致性,并允许读取操作与正在进行的复制同时发生,而无需上锁。因此,对于需要这些读关注(read concern)级别的从节点读取请求来说,它们不再需要等待复制批次在从节点上生效,而是可以在被从节点收到时即刻被处理。
流量控制
管理员可以限制主节点应用写入的速率,目标是将 majority
committed
延迟保持在可配置的最大 flowControlTargetLagSeconds
值以下。
默认情况下,流量控制为 enabled
。
注意
要启用流量控制,副本集/分片集群必须具有: featureCompatibilityVersion (fCV) 为 4.2
,且读关注(read concern)为 majority enabled
。也就是说,如果 fCV 不是 4.2
或读关注已被禁用,则已启用的流量控制将不会生效。
有关详细信息,请参阅流量控制。
复制同步源选择
复制源成员选择取决于副本集chaining
设置:
启用链接后(默认),从目标成员中执行源成员选择。
禁用链接后,选择主节点作为源节点。如果主节点不可用或无法访问,请记录错误并定期检查主节点的可用性。
执行复制源成员选择的成员会对所有副本集成员的列表进行两次遍历:
在第一次选择源节点时,节点将以下条件应用于每个副本集节点:
源成员必须在线且可访问。
源成员必须具有比该成员更新的 oplog 条目。也就是说,源成员必须位于成员之前。
源成员必须是
visible
。源节点必须 在主节点上最新 oplog 条目的
30
秒之内。如果成员
builds indexes
,则源成员必须构建索引。如果副本集内的节点
votes
进行选举,则源节点也必须投票。如果该成员不是
delayed member
,则不得延迟源成员。如果成员是
delayed member
,则源成员必须配置更短的延迟。源成员必须比当前最佳同步源更快。
如果在第一次遍历后没有保留候选源成员,则该成员会使用宽松的标准执行第二次遍历。请参阅Sync Source Selection (Second Pass) 。
在第二轮选择源节点时,节点对每个副本集节点应用以下条件:
源成员必须在线且可访问。
如果成员
builds indexes
,则源成员必须构建索引。源成员必须比当前最佳同步源更快。
如果该成员在两次传递后无法选择同步源,则会记录一则错误并等待 1
秒,然后重新启动选择流程。
每小时可以更改源成员的次数可以通过设置maxNumSyncSourceChangesPerHour
参数来配置。
注意
选择初始同步源成员时,启动参数initialSyncSourceReadPreference
优先于副本集的settings.chainingAllowed
设置。副本集节点成功执行初始同步后,在选择源节点时会延迟chainingAllowed
的值。
请参阅初始同步源选择,详细了解初始同步源选择。