读取偏好描述 MongoDB 客户端如何将读取操作路由到副本集的节点。
默认情况下,应用程序将其读取操作定向到副本集的主节点(即读取偏好模式“主节点”)。但是,客户端可以指定读取偏好以将读取操作发送到从节点。
读取偏好由读取偏好模式、可选标签集列表和 maxStalenessSeconds 选项组成。
读取偏好模式
下表总结了读取偏好(read preference)模式。
读取偏好模式 | 说明 |
|---|---|
默认模式。从当前副本集主节点 (primary node in the replica set)读取的操作。 包含读取操作的事务必须使用读取偏好(read preference) | |
操作从主节点 (primary node in the replica set)读取(如果可用)。如果不是,则从符合条件的从从节点(secondary node from replica set)读取。 | |
操作从副本集符合条件的从从节点(secondary node from replica set)读取数据。如果没有符合条件的可用从节点,则操作将从主节点 (primary node in the replica set)节点读取。 | |
操作从网络延迟在延迟窗口内且符合条件的成员中读取,无论它是主节点 (primary node in the replica set)还是从节点(secondary node from replica set)。 |
对于所有模式,当节点响应客户端的定期监控检查时,该节点可用,这些检查确认该节点可通过网络访问并且能够响应请求。
对于除
primary之外的所有模式,如果成员满足读取偏好的 maxStalenessSeconds 选项和任何指定的标签集列表,则该成员符合资格。
重要
读取偏好模式不保证操作成功。可用性和资格决定了客户端会考虑哪些节点,但所选节点仍可拒绝操作,例如当节点处于负载状态时。
有关读取偏好模式的详细说明,请参阅读取偏好模式。
行为
All read preference modes except
primarymay return stale data because secondaries replicate operations from the primary in an asynchronous process. [1] Ensure that your application can tolerate stale data if you choose to use a non-primarymode.读取偏好不影响数据的可见性。客户端可以在写入结果被确认或传播到大多数副本集节点之前看到写入结果。有关详细信息,请参阅读取隔离、一致性和新近度。
读取偏好不会影响因果一致性。因果一致性会话为具有
"majority"读关注的读取操作以及具有"majority"写关注的写入操作提供的因果一致性保证适用于 MongoDB 部署的所有节点。
警告
从MongoDB版本 8.2 开始,分片集群中长时间运行的从节点(secondary node from replica set)读取可能会在数据块迁移后删除孤立文档之前自动终止。
terminateSecondaryReadsOnOrphanCleanup 参数控制此行为。要学习;了解有关处理长时间运行的从节点(secondary node from replica set)读取的更多信息,请参阅分片集群中长时间运行的从节点读取。
读取偏好模式
primaryAll read operations use only the current replica set primary. [1] This is the default read mode. If the primary is unavailable, read operations produce an error or throw an exception.
primary读取偏好模式与使用标记集列表或 maxStalenessSeconds 的读取偏好模式不兼容。如果指定标记集列表或带有primary的maxStalenessSeconds值,则驱动程序将产生错误。包含读取操作的事务必须使用读取偏好(read preference)
primary。给定ACID 事务中的所有操作必须路由到同一成员。
primaryPreferred操作从设立的主节点 (primary node in the replica set)节点读取(如果可用)。如果主节点 (primary node in the replica set)不可用,例如在故障转移情况下,则操作将从满足读取偏好的
maxStalenessSeconds和标签集列表的从从节点(secondary node from replica set)成员读取。当
primaryPreferred读取偏好包含 maxStalenessSeconds 值且没有可供读取的主节点时,客户端会通过将从节点的最后一次写入与执行最近一次写入的从节点进行比较,从而估计每个从节点的陈旧程度。然后,客户端会将读取操作定向到估计延迟小于或等于maxStalenessSeconds的从节点。当读取偏好包含标签集列表(标签集数组)时且没有可读取的主节点时,客户端会尝试查找具有匹配标签的从节点(按顺序尝试标签集,直到找到匹配项)。如果找到匹配的从节点,则客户端会从最近的匹配从节点群组中随机选择一个从节点。如果从节点没有匹配的标签,读取操作就会出错。
当读取偏好包含
maxStalenessSeconds值和标签集列表时,客户端首先按过时程度筛选,然后按指定标签筛选。使用
primaryPreferred模式进行读取操作可能会返回过时数据。使用maxStalenessSeconds选项避免从客户端估计过于陈旧的从节点读取数据。在启用入口请求速率限制器的分片的片集群中,卸载负载的分片节点可能会返回标记为
SystemOverloadedError的错误。对于将
overloadAwareServerSelectionEnabled设立为true的集群,当主节点 (primary node in the replica set)响应标记为SystemOverloadedError的可重试错误时,路由器可能会临时将读取操作路由到符合条件的从节点,而不是过载的服务器。这适用于任何可以选择多个服务器的读取偏好(read preference)。默认下,overloadAwareServerSelectionEnabled设立为false。
secondary操作只能从副本集的从节点读取。如果没有可用的从节点,则此读取操作会出现错误或异常。
大多数副本集至少有一个从节点(secondary node from replica set),但在某些情况下可能没有可用的从节点(secondary node from replica set)。示例,如果成员处于恢复状态或不可用,则具有主节点 (primary node in the replica set)、从节点(secondary node from replica set)和仲裁节点的副本集可能没有任何从节点。
当
secondary读取偏好包含 maxStalenessSeconds 值时,客户端通过将从节点的最后一次写入与主节点进行比较来估计每个从节点的过时程度。然后,客户端会将读取操作定向到估计延迟小于或等于maxStalenessSeconds的从节点。如果没有主节点,客户端将使用最近写入的从节点进行比较。当读取偏好包含标签集列表(标签集数组)时,客户端会尝试查找具有匹配标签的从节点成员(按顺序尝试标签集,直到找到匹配项)。如果找到匹配的从节点,则客户端会从最近的匹配从节点群组中随机选择一个从节点。如果从节点没有匹配的标签,读取操作就会出错。
当读取偏好包含
maxStalenessSeconds值和标签集列表时,客户端首先按过时程度筛选,然后按指定标签筛选。使用
secondary模式进行读取操作可能会返回过时数据。使用maxStalenessSeconds选项避免从客户端估计过于陈旧的从节点读取数据。
secondaryPreferred操作从副本集符合条件的从从节点(secondary node from replica set)读取数据。如果没有符合条件的可用从节点,则操作将从主节点 (primary node in the replica set)节点读取。
当
secondaryPreferred读取偏好包含 maxStalenessSeconds 值时,客户端通过将从节点的最后一次写入与主节点进行比较来估计每个从节点的过时程度。然后,客户端会将读取操作定向到估计延迟小于或等于maxStalenessSeconds的从节点。如果没有主节点,客户端将使用最近写入的从节点进行比较。如果没有估计滞后小于或等于maxStalenessSeconds的从节点,则客户端会将读取操作定向到副本集的主节点。当读取偏好包含标签集列表(标签集数组)时,客户端会尝试查找具有匹配标签的从节点成员(按顺序尝试标签集,直到找到匹配项)。如果找到匹配的从节点,则客户端会从最近的匹配从节点群组中随机选择一个从节点。如果不存在具备匹配标签的从节点,则客户端忽略标签并从主节点读取。
当读取偏好包含
maxStalenessSeconds值和标签集列表时,客户端首先按过时程度筛选,然后按指定标签筛选。使用
secondaryPreferred模式进行读取操作可能会返回过时数据。使用maxStalenessSeconds选项避免从客户端估计过于陈旧的从节点读取数据。
nearest驾驶员从网络延迟处于可接受延迟窗口内的成员处读取数据。
nearest模式下的读取在路由读取操作时不考虑成员是主节点 (primary node in the replica set)还是从节点(secondary node from replica set):主节点和从节点被同等对待。设置此模式可最大限度地减少网络延迟对读取操作的影响,而不会优先考虑当前或过时的数据。
当读取偏好包含 maxStalenessSeconds 值时,客户端会通过将从节点的最后一次写入与主节点的最后一次写入(如果可用)进行比较来估计每个从节点的陈旧程度;或者,如果没有主节点,则会将其与执行最近一次写入的从节点进行比较。然后,客户端会过滤掉其估计延迟大于
maxStalenessSeconds的所有从节点,并将此读取操作随机定向到网络延迟不超过可接受延迟窗口的其余节点(主节点或从节点)。如果指定标签集列表,则客户端会尝试查找与指定标签集列表匹配的副本集节点,并将读取定向到最近的群组中的任意节点。
当读取偏好包含
maxStalenessSeconds值和标签集列表时,客户端首先按过时程度筛选,然后按指定标签过滤。然后,客户端从剩余的mongod实例中,随机将读取定向到处于可接受延迟时间范围内的实例。读取偏好节点选择文档详细描述了该过程。使用
nearest模式进行读取操作可能会返回过时数据。使用maxStalenessSeconds选项避免从客户端估计过于陈旧的从节点读取数据。
提示
要了解特定读取偏好设置的使用案例,请参阅读取偏好使用案例。
配置读取偏好
使用 MongoDB 驱动程序时,您可以使用驱动程序的读取偏好 API 指定读取偏好。请参阅驱动程序 API 文档 。您还可以在连接到副本集或分片集群时设立读取偏好(read preference)。有关示例,请参阅连接字符串。
对于给定的读取偏好,MongoDB 驱动程序使用相同的节点选择逻辑。
使用 mongosh 时,请参阅 cursor.readPref() 和 Mongo.setReadPref()。
读取偏好和事务
包含读取操作的事务必须使用读取偏好(read preference)primary。给定ACID 事务中的所有操作必须路由到同一成员。
其他注意事项
在聚合管道中使用 $merge 或 $out 阶段时,请考虑以下几点:
从 MongoDB 5.0 开始,如果集群中的所有节点都将 featureCompatibilityVersion 设置为
5.0或更高,并且读取偏好允许辅助读取,则具有$merge阶段的管道可以在副本集辅助节点上运行。在早期的 MongoDB 版本中,具有
$out或$merge阶段的管道始终在主节点上运行,并且不考虑读取偏好。
对于 mapReduce 操作,只有“inline”不写入数据的mapReduce 操作支持读取偏好(read preference)。否则,mapReduce 操作将在主节点 (primary node in the replica set)节点上运行。
| [1] | (1, 2) 在某些情况下,副本集中的两个节点可能会暂时认为它们是主节点,但最多只能有其中一个节点能够完成具有 |