参考 > 复写 > 复制集读取和写入语义 > 阅读偏好
读取首选项描述了MongoDB客户端如何将读取操作路由到副本集的成员。
默认情况下,应用程序将其读取操作定向到副本集中的 主要成员(即读取首选项模式“主要”)。但是,客户端可以指定读取首选项,以将读取操作发送到辅助对象。
读取首选项由读取首选项模式以及标签集和 读取首选项maxStalenessSeconds组成。
读取首选项模式 | 描述 |
---|---|
primary |
默认模式。所有操作均从当前副本集primary中读取 。 |
primaryPreferred |
在大多数情况下,操作从主服务器读取,但如果不可用,则从辅助 成员读取操作。 |
secondary |
所有操作均从副本集的辅助成员读取。 |
secondaryPreferred |
在大多数情况下,操作会从辅助 成员读取,但如果没有辅助成员可用,则操作会从primary读取。 |
nearest |
从副本集的成员读取的操作具有最小的网络延迟,而与成员的类型无关。 |
primary
可能返回陈旧的数据,因为在异步过程中,辅助服务器从主服务器复制操作。
[1]如果您选择使用非primary
模式,请确保您的应用程序可以容忍陈旧的数据。"majority"
读取关注的读取操作
和具有"majority"
写入关注的写入操作
。primary
¶所有读取操作仅使用当前副本集 primary。[1]这是默认的读取模式。如果主数据库不可用,则读取操作会产生错误或引发异常。
primary
读取首选项模式与使用标签集或maxStalenessSeconds的读取首选项模式不兼容。如果使用指定标签集或maxStalenessSeconds
值primary
,则驱动程序将产生错误。
primaryPreferred
¶在大多数情况下,操作将从集合的主要成员读取。但是,如果主服务器不可用(如故障转移情况下的情况),
则将从满足读取首选项和标记集的辅助成员读取操作maxStalenessSeconds
。
当primaryPreferred
读取首选项包含maxStalenessSeconds值并且没有要读取的主数据库时,客户端通过将辅助数据库的上次写入与最近一次写入的辅助数据库的比较来估计每个辅助数据库的陈旧程度。然后,客户端将读取操作定向到估计延迟小于或等于的辅助节点maxStalenessSeconds
。
当读取的首选项包括标签集(即标签规范列表)并且没有要读取的主要标签时,客户端将尝试查找具有匹配标签的辅助成员(按顺序尝试标签规范,直到找到匹配项)。如果找到匹配的次级,则客户端从最近的一组匹配次级中选择一个随机的次级。如果没有辅助节点具有匹配的标签,则读取操作将产生错误。
当读取的首选项包含一个maxStalenessSeconds
值
和一个标记集时,客户端将首先按陈旧性过滤,然后按指定的标记过滤。
使用该primaryPreferred
模式的读取操作可能会返回陈旧数据。使用该
maxStalenessSeconds
选项可避免从辅助对象中读取客户估计过时的内容。
secondary
¶操作仅从集合的次要成员中读取。如果没有备用副本,则此读取操作将产生错误或异常。
大多数副本集至少具有一个辅助副本,但是在某些情况下可能没有可用的辅助副本。例如,如果成员处于恢复状态或不可用,则具有主服务器,辅助服务器和 仲裁器的副本集可能没有任何辅助服务器。
当secondary
读取首选项包含maxStalenessSeconds值时,客户端通过将辅助节点的上次写入与主要节点的上次写入进行比较,来估计每个辅助节点的过时程度。然后,客户端将读取操作定向到估计延迟小于或等于的辅助节点maxStalenessSeconds
。如果没有主服务器,客户端将使用具有最新写入操作的辅助服务器进行比较。
当读取的首选项包括标签集(即标签规范列表)时,客户端尝试查找具有匹配标签的辅助成员(按顺序尝试标签规范,直到找到匹配项)。如果找到匹配的次级,则客户端从最近的一组匹配次级中选择一个随机的次级。如果没有辅助节点具有匹配的标签,则读取操作将产生错误。
当读取的首选项包含一个maxStalenessSeconds
值
和一个标记集时,客户端将首先按陈旧性过滤,然后按指定的标记过滤。
使用该secondary
模式的读取操作可能会返回陈旧数据。使用该
maxStalenessSeconds
选项可避免从辅助对象中读取客户估计过时的内容。
secondaryPreferred
¶在大多数情况下,操作从辅助成员读取,但是在集合由单个主要成员(无其他成员)组成的情况下 ,读取操作将使用副本集的主要成员。
当secondaryPreferred
读取首选项包含maxStalenessSeconds值时,客户端通过将辅助节点的上次写入与主要节点的上次写入进行比较,来估计每个辅助节点的过时程度。然后,客户端将读取操作定向到估计延迟小于或等于的辅助节点maxStalenessSeconds
。如果没有主服务器,客户端将使用具有最新写入操作的辅助服务器进行比较。如果不存在估计延迟小于或等于的辅助对象maxStalenessSeconds
,则客户端会将读取操作定向到副本集的主对象。
当读取的首选项包括标签集(即标签规范列表)时,客户端尝试查找具有匹配标签的辅助成员(按顺序尝试标签规范,直到找到匹配项)。如果找到匹配的次级,则客户端从最近的一组匹配次级中选择一个随机的次级。如果没有辅助节点具有匹配的标签,则客户端将忽略标签并从主节点读取。
当读取的首选项包含一个maxStalenessSeconds
值
和一个标记集时,客户端将首先按陈旧性过滤,然后按指定的标记过滤。
使用该secondaryPreferred
模式的读取操作可能会返回陈旧数据。使用该
maxStalenessSeconds
选项可避免从辅助对象中读取客户估计过时的内容。
nearest
¶驱动程序从其网络延迟在可接受的延迟窗口内的成员读取。在nearest
路由读取操作时,该模式下的读取不考虑成员是主要成员还是次要成员:主要和次要成员被同等对待。已读首选项成员选择文档详细描述了该过程。
设置此模式可最大程度地减少网络延迟对读取操作的影响,而无需优先考虑当前或过时的数据。
当读取首选项包含maxStalenessSeconds值时,客户端将比较辅助节点的上次写入与主节点(如果有)的上次写入(如果有的话),或者与没有辅助节点的最近写入进行比较,以估计每个辅助节点的过时状态。然后,客户端将滤除估计滞后时间大于其值的任何辅助
maxStalenessSeconds
节点,并将读取结果随机定向到其网络延迟落在可接受的延迟窗口内的其余成员(主要节点或辅助节点)
。
如果指定标签集,客户端将尝试查找与指定标签集匹配的副本集成员,并将读取结果定向到最近的组中的任意成员。
当读取的首选项包含一个maxStalenessSeconds
值
和一个标记集时,客户端将首先按陈旧性过滤,然后按指定的标记过滤。mongod
然后,客户端将从其余实例中随机将读取定向到可接受的等待时间窗口内的实例。已读首选项成员选择
文档详细描述了该过程。
使用该nearest
模式的读取操作可能会返回陈旧数据。使用该
maxStalenessSeconds
选项可避免从辅助对象中读取客户估计过时的内容。
使用MongoDB驱动程序时,可以在连接到副本集或分片集群时指定读取首选项 。例如,请参阅连接字符串。您还可以在更详细的级别上指定读取首选项。有关详细信息,请参见驱动程序的 api文档。
对于给定的读取首选项,MongoDB驱动程序使用相同的 成员选择逻辑。
使用mongo
外壳时,请参见cursor.readPref()
和Mongo.setReadPref()
。例如:
对于聚合管道
操作,如果管道包括$out
阶段或$merge
阶段,则必须在主管道上运行。
对于mapReduce
操作,仅mapReduce
不写入数据的“内联”
操作支持读取首选项。否则,mapReduce
操作必须在主要成员上运行。
[1] | (1,2)在某些情况下,副本集中的两个节点可能暂时相信他们是主要的,但最多,其中一人将能够完全写入的写入关注。可以完成
写入操作的节点是当前主节点,另一个节点是以前的主节点,由于网络分区,该主节点尚未意识到其降级。发生这种情况时,尽管已请求读取首选项,但连接到前主数据库的客户端可能仍会观察到过时的数据
,并且对前主数据库的新写入最终将回滚。{ w:
"majority" } { w: "majority" } primary |