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