MongoDB 中 副本集 是一组 mongod进程,其保持相同的数据集。副本集提供了冗余和 高可用性,并且是生产部署 的基础。
复制提供冗余并提高 数据可用性。使用不同数据库服务器上的多个数据副本,复制可提供一定程度的容错能力,以防止单个数据库服务器故障。
在某些情况下,复制可以提供更大的读取容量,因为客户端可以将读取操作发送到不同的服务器。在不同数据中心中维护数据副本可以提高数据本地性和分布式应用程序的可用性。您还可以维护其他副本以用于专用目的,例如灾难恢复,报表或备份。
replica set是一组 mongod维护相同数据集的实例。一个副本集包含多个数据承载节点和一个仲裁器节点(可选)。在数据承载节点中,只有一个成员被视为主要节点,而其他节点则被视为次要节点。
Primary : 主服务器接收所有写操作。
Secondaries . 辅助数据库从主数据库复制操作以维护相同的数据集。辅助服务器可能具有用于特殊用途配置文件的其他配置。例如,次级可以 是 无表决权或 优先级0 。
副本集的最低建议配置是具有三个数据承载成员的三个成员副本集:一个 主要成员和两个 次要成员。在某些情况下(例如,您有一个主服务器和一个辅助服务器,但由于成本限制,禁止添加另一个辅助服务器),您可以选择包括一个 仲裁 节点。仲裁节点加 选举,但不保存数据(即不提供数据冗余)。
一个副本集最多可以有 50 个成员,但只有7个投票成员。
主节点接收所有写操作。一个副本集只能有一个主副本,能够确认具有{w: majority}写关注点的写操作;尽管在某些情况下,另一个mongod实例可能会暂时认为自己也是主副本。[1] 主服务器在其操作日志(即oplog)中记录对其数据集的所有更改。
二级数据库复制主数据库的oplog并将操作应用于它们的数据集,以便二级数据库的数据集反映主数据库的数据集。如果不可用,一个可用的 secondary 将选举自己成为新的primary节点。
不能 成为primary 和 参与 选举 。
隐藏成员维护主数据集的副本,但对客户端应用程序是不可见的。 隐藏成员适用于使用模式与副本集中其他成员不同的工作负载。隐藏成员必须始终是优先级为0的成员,因此不能成为primary。 db.isMaster() 不显示隐藏成员。然而,隐藏成员可以在选举中投票。
延迟的成员包含 副本集数据集的 副本。但是,延迟成员的数据集反映了该集的较早或延迟的状态。例如,如果当前时间是09:52,并且成员有一个小时的延迟,则延迟的成员没有比08:52更新的操作。
由于延迟成员是数据集的“滚动备份”或运行中的“历史”快照,因此它们可以帮助从各种人为错误中恢复。例如,延迟成员可以从失败的应用程序升级和操作员错误(包括删除的数据库和集合)中恢复。
延迟成员:
在某些情况下(例如您有一个主服务器和一个辅助服务器,但由于成本限制,禁止添加另一个辅助服务器),您可以选择将一个 mongod实例作为 仲裁 节点添加到副本集 。仲裁节点参加 选举,但不保存数据(即不提供数据冗余)。
仲裁节点不可成为主节点。
OPLOG(操作日志)是一个特殊的 固定 集合( capped collection),它可将修改数据的所有操作的滚动记录存储在数据库中。
在版本 4.0 中进行了更改:从 MongoDB 4.0 开始,与其他固定集合不同, oplog 可以增长超过其配置的大小限制,以避免删除大多数提交点。
版本 4.4 中的新增功能: MongoDB 4.4支持指定以小时为单位的最小oplog保留期限,其中MongoDB仅在以下情况下删除oplog条目:
MongoDB在 主数据库上应用数据库操作,然后在 主数据库的操作日志中记录该操作。然后, 辅助成员将这些操作复制并应用到异步过程中。所有副本集成员在 local.oplog.rs集合中都包含操作日志的副本 ,这使他们可以维护数据库的当前状态。
为了促进复制,所有副本集成员都将心跳(ping)发送给所有其他成员。任何 辅助成员都可以从任何其他成员导入操作日志条目。
oplog中的每个操作都是 幂等的。也就是说,oplog操作会产生相同的结果,无论是一次还是多次应用于目标数据集。
首次启动副本集成员时,如果未指定操作日志大小,则MongoDB会创建默认大小的操作日志。 [1]
对于 Unix 和 Windows 系统
默认操作日志大小取决于存储引擎:
|
储存引擎 |
默认Oplog大小 |
下界 |
上界 |
|
In-Memory 存储引擎 |
物理内存的5% |
50MB |
50 GB |
|
WiredTiger 存储引擎 |
可用磁盘空间的5% |
990MB |
50 GB |
对于 64 位 macOS 系统
默认操作日志大小为 192 MB 的物理内存或可用磁盘空间,具体取决于存储引擎:
|
储存引擎 |
默认Oplog大小 |
|
In-Memory 存储引擎 |
192 MB的物理内存 |
|
WiredTiger 存储引擎 |
192 MB的可用磁盘空间 |
在大多数情况下,默认操作日志大小已足够。例如,如果操作日志是可用磁盘空间的 5 %,并且在 24 小时的操作中已满,则辅助服务器可以在长达 24 小时的时间内停止从操作日志中复制条目,而不会过时而无法继续复制。但是,大多数副本集的操作量要低得多,并且它们的 oplog 可以容纳更多的操作。
在 mongod创建操作日志之前,您可以使用 oplogSizeMB选项指定其大小。首次启动副本集成员后,请使用 replSetResizeOplog管理命令更改操作日志大小。 replSetResizeOplog使您能够动态调整操作日志的大小,而无需重新启动 mongod进 程。
4.4 版的新功能: 从 MongoDB 4.4 开始,您可以指定保留 oplog 条目的最小时间。该 mongod 只截断的 OPLOG 项 ,如果:
默认情况下, MongoDB 不会设置最小操作日志保留期限,而是从最早的条目开始自动截断操作日志,以维持配置的最大操作日志大小。
4.4 版的新功能: 从 MongoDB 4.4 开始,您可以指定保留 oplog 条目的最小时间。 mongod 仅移除一个 OPLOG ,如果 :
默认情况下, MongoDB 不会设置最小操作日志保留期限,而是从最早的条目开始自动截断操作日志,以维持配置的最大操作日志大小。
要在启动时配置最小操作日志保留期 mongod ,请执行以下任一操作:
- 要么 -
要在运行中配置最小 oplog 保留期限 mongod ,请使用 replSetResizeOplog 。在 mongod 运行时设置最小 oplog 保留期限将覆盖启动时设置的所有值。您必须更新相应的配置文件设置或命令行选项的值,以通过服务器重新启动来保留这些更改。
如果您可以预测副本集的工作量类似于以下模式之一,则可能需要创建一个大于默认值的操作日志。相反,如果您的应用程序主要以最少的写操作执行读取,则较小的操作日志可能就足够了。
以下工作负载可能需要更大的 oplog 大小。
操作日志必须将多次更新转换为单独的操作,以保持 幂等性 。这会占用大量操作日志空间,而不会相应增加数据大小或磁盘使用量。
如果删除与插入时大致相同的数据量,则数据库在磁盘使用方面不会显着增长,但是操作日志的大小可能会很大。
如果工作量的很大一部分是不增加文档大小的更新,则数据库会记录大量操作,但不会更改磁盘上的数据量。
要查看操作日志状态,包括操作的大小和时间范围,请发出该 rs.printReplicationInfo() 方法。
从版本 4.2 开始(也可从 4.0.6 开始使用),副本集的辅助成员现在会记录需要比慢速操作阈值更长时间才能应用的 oplog 条目。这些慢 oplog 消息记录在 REPL 组件下的诊断日志中,并带有文本 applied op:<oplog entry>take<num>ms 。这些慢 oplog 条目仅取决于慢操作阈值。它们不依赖于日志级别(系统或组件级别)、分析级别或慢操作采样率。探查器不会捕获较慢的 oplog 条目。
复制 延时 是指将 主磁盘上的写操作复制到 辅助节点上的时间 。可以接受一些小的延迟时间,但是随着复制延时的增加会出 现严重的问题,包括在主数据库上增加缓存压力。
从 MongoDB 4.2 开始,管理员可以限制主应用其写入的速率,目的是将大多数提交的延迟保持在可配置的最大值 flowControlTargetLagSeconds 下。
默认情况下,流控 制为 enabled 。
注:要启用流控制,副本集 / 分片群集必须: featureCompatibilityVersion ( FCV )是 4.2 版本及开启 read concern majority 。也就是说,如果 FCV 不是 4.2 或者如果 read concern majority 被禁用,那么流控制将不起作用。
在启用流控制的情况下,随着延迟接近 flowControlTargetLagSeconds ,主服务器上的写操作必须在获取锁以应用写操作之前获取 tickets 。通过限制每秒发行的 tickets 数量,流控制机制试图将延迟保持在目标值以下。
辅助节点复制主节点的操作日志,并将操作异步应用于其数据集。通过使辅助数据库的数据集反映主要数据库的数据集,即使一个或多个成员失败,副本集也可以继续运行。
当主节点与集合中的其他成员的通信 electionTimeoutMillis 时间超过配置的时间段(默认为 10 秒)时,可用的辅助节点将要求选举以提名自己为新的主节点。群集尝试完成新主数据库的选择并恢复正常操作。
副本集无法处理写入操作,直到选举成功完成。如果将副本集配置为在主副本处于脱机状态 时 在次副本上 运行, 则副本集可以继续提供读取查询 。
假设默认的副本配置设置,集群选择新主服务器之前的平均时间通常不应超过 12 秒。这包括将初选标记为不可用、调用和完成选举所需的时间。您可以通过修改 settings.electionTimeoutMillis 设置复制配置选项。诸如网络延迟之类的因素可能会延长完成副本集选择所需的时间,进而影响群集在没有主服务器的情况下运行的时间。这些因素取决于特定的集群体系结构。
将 electionTimeoutMillis 复制配置选项从默认值 10000 ( 10 秒)降低可以更快地检测主故障。然而,由于诸如临时网络延迟之类的因素,集群可能更频繁地调用选举,即使主节点在其他方面是健康的。这可能导致 w:1 写操作的回滚增加。
应用程序连接逻辑应包括对自动故障切换和后续选择的容忍度。从 MongoDB 3.6 开始, MongoDB 可以检测到主设备的丢失,并自动重试某些写入操作一次,从而提供自动故障切换和选择的额外内置处理:
从 4.4 版开始, MongoDB 提供 镜像读取, 以使用最近访问的数据预热可选举的次要成员的缓存。预热辅助服务器的缓存可以帮助在选举后更快地恢复性能。
副本集的 Write concern 描述了在操作返回成功之前必须确认写操作的数据承载成员(即主要成员和次要成员,但不是仲裁节点)的数量。成员只能在成功接收并应用写操作之后才确认写操作。
对于副本集, w:1 的默认 Write concern 要求只有主副本集成员在返回写入关注点确认之前确认写入。您可以指定一个大于 1 的整数值,以要求主副本进行确认,并根据需要指定多个辅助副本来满足指定的值,最多为副本集中承载数据的成员总数。
Write concern 为“ majority ”的写入操作要求确认写入操作已传播到数据承载投票成员的计算多数。对于成员已启用日志记录的集群,将“ majority ” Write concern 与 j:true 结合可以防止 Write concern 确认后的数据的回滚。
默认情况下,应用程序将其读取操作定向 到 副本集中的 primary 成员(即读取首选项模式“ primary ”)。但 是,客户端可以指定读取首选项,以将读取操作发送到辅助对象。
|
读取首选项模式 |
描述 |
|
primary |
默认模式。所有操作均从当前副本集 primary 中读取 。 包含读取操作的 多文档事务必须使用读取首选项 primary。给定事务中的所有操作都必须路由到同一成员。 |
|
primaryPreferred |
在大多数情况下,操作从 主服务器读取,但如果不可用,则从 辅助 成员读取操作。 从版本4.4开始, primaryPreferred支持分片 群集上的树篱 读取。 |
|
secondary |
所有操作均从副本集的 辅助成员读取。 从版本4.4开始, secondary支持分片 群集上的树篱 读取。 |
|
secondaryPreferred |
在大多数情况下,操作从 辅助 成员读取,但是如果没有 辅助成员可用,则操作从分片群集的 主成员读取。 从版 本4.4开始, secondaryPreferred支持分片 群集上的树篱 读取 。 |
|
nearest |
基于指定的等待时间 阈值,从随机的合格 副本集 成员读取操作,而不管该成员是 主要 副本 还是 次要 副本。该操作在计算延迟时会考虑以下因素:
从版本 4.4 开始, nearest 支持分片 群集上的树篱 读取 ,并且默认情况下启用树篱读取选项。 |
异步复制 到辅助数据库意味着从辅助数据库读取数据可能会返回不反映主数据库上数据状态的数据。
多文档事务 的读取必须使用 read preference primary 。给定事务中的所有操作都必须路由到同一成员。
根据读取的关注点,客户端可以在 持久 写入 之前看到写入的结果:
对于 多文档事务中的操作 ,在提交 事务时 ,将保存在事务中进行的所有数据更改,并在事务外部可见。也就是说,事务在回滚其他事务时将不会提交更改。
在提交事务之前,在事务外部看不到在事务中进行的数据更改。
但是,当一个事务写入多个分片时,并非所有外部读取操作都需要等待提交的事务的结果在分片中可见。例如,如果事务已提交,并且write 1在shard a上可见,但write 2在shard B上尚不可见,则外部read concern “local”可以读取write 1的结果,而不会看到write 2。
从版本 4.4 开始, MongoDB 提供镜像读取来预热可选辅助成员(即优先级大于 0 的成员)的缓存。使用镜像读取(默认情况下启用),主服务器可以镜像它接收的操作子集,并将它们发送到可选择的辅助服务器子集。子集的大小是可配置的。
注意:
主服务器对客户端的响应不受镜像读取的影响。镜像读取是由主服务器执行的“ fire-and-forget ”操作;即,主服务器不等待镜像读取的响应。
以下操作支持镜像读取:
在 MongoDB 4.4 中,默认情况下启用镜像读取,并使用默认采样率 0.01 。也就是说,主镜像以 1% 的采样率读取每个可选(即优先级大于 0 )次镜像。
例如,给定一个副本集,该副本集有一个主副本和两个可选的辅助副本,采样率为 0.01 ,如果主副本接收到 100 个可以镜像的操作,则采样可能导致 1 个读取镜像到一个辅助副本, 0 个读取镜像到另一个副本,或 0 个读取镜像到每个副本,以此类推。
要修改采样率,请使 用 mirrorReads 参数:
从 MongoDB 4.4 开始,如果您在操作中指定了字段的包含内容,则该命令 serverStatus 及其相应的 mongoshell方法 将 db.serverStatus() 返回 mirroredReads 。例如,
db.serverStatus( { mirroredReads: 1 } )
从 MongoDB 4.0 开始, 多文档事务 可用于副本集。
多文档事务 的读取必须使用 read preference primary 。给定事务中的所有操作都必须路由到同一成员。
在提交事务之前,在事务外部看不到在事务中进行的数据更改。
但是,当一个事务写入多个分片时,并非所有外部读取操作都需要等待提交的事务的结果在分片中可见。例如,如果事务已提交,并且write 1在shard a上可见,但write 2在shard B上尚不可见,则外部read concern “local”可以读取write 1的结果,而不会看到write 2。
从 MongoDB 3.6 开始, change streams 可用于副本集和分片群集。 change streams 允许应用程序访问实时数据更改,而不会带来复杂性和拖延操作日志的风险。应用程序可以使用 change streams 来订阅一个或多个集合上的所有数据更改。
副本集提供了许多选项来支持应用程序需要。例如,您可以在多个数据中心部署具有成员的副本集,或者通过调整某些成员的成员 [n]. 优先级来控制选举结果。副本集还支持用于报告、灾难恢复或备份功能的专用成员。
从运行方法的成员的角度返回副本集状态。此方法为 replSetGetStatus 命令提供了包装 。
此输出使用从副本集其他成员发送的心跳数据包派生的数据反映副本集的当前状态。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69993564/viewspace-2756255/ ,如需转载,请注明出处,否则将追究法律责任。