Overview
所有MongoDB驱动程序在选择要读取或写入的服务器时都遵循定义的算法。 MongoDB Rust驱动程序允许您自定义此算法,以选择最适合您的应用程序的服务器。
您可以通过以下方式影响服务器选择:
使用读取偏好(read preference)以标准化方式描述合适的服务器,例如主节点 (primary node in the replica set)、从节点(secondary node from replica set)或带有标签集和最大过时度的最近服务器。
通过
SelectionCriteria::Predicate提供自定义谓词,以在筛选合适的服务器时应用您自己的逻辑。
重要
自定义服务器选择算法可能会产生意想不到的后果,例如读取或写入性能下降。
自定义选择算法
当Rust驾驶员使用自定义选择条件执行操作时,它会执行以下步骤以选择MongoDB 部署:
选择符合条件的服务器:从已知服务器列表中,驾驶员选择与活动
SelectionCriteria匹配的服务器,无论是与读取偏好(read preference)匹配的服务器,还是自定义谓词为其返回true的服务器。应用延迟窗口:驾驶员将
local_threshold设置应用于符合条件的服务器列表,筛选出平均往返时间超出最快符合条件服务器的已配置窗口的任何服务器。随机选择:驾驶员从延迟窗口中剩余的服务器中随机选择一个服务器,并针对该服务器执行操作。
当Rust驾驶员执行写入操作时,它首先选择所有可写入的服务器,而不仅仅是那些与活动读取偏好(read preference)匹配的服务器。其余步骤相同。
SelectionCriteria 和 Predicates
Rust驾驶员使用 SelectionCriteria枚举表示服务器选择规则,如以下示例所示:
pub enum SelectionCriteria { ReadPreference(ReadPreference), Predicate(Predicate), }
对于任何给定操作,您可以使用 SelectionCriteria::ReadPreference 或 SelectionCriteria::Predicate,而不是同时使用:
ReadPreference:根据标准MongoDB读取偏好(read preference)规则,根据服务器类型、标签集和最大过时度描述合适的服务器。Predicate:使您能够为ReadPreference无法表达的情况提供自定义逻辑,例如根据主机名模式或其他自定义条件选择服务器。
谓词是任何接受 ServerInfo 引用并返回 true 的闭包,以指示服务器的适用性。驾驶员将其定义为类型别名 Predicate,如以下代码所示:
pub type Predicate = Arc<dyn Send + Sync + Fn(&ServerInfo) -> bool>;
当谓词为服务器的 ServerInfo 值返回 true 时,则认为该服务器是合适的。 ServerInfo 类型公开有关服务器的信息,例如解决、类型和其他监控元数据。
示例:使用谓词选择本地主机上的服务器
如果您使用具有多个 mongos 服务器的分片集群,您可能更喜欢在 localhost 上运行的部署。针对这些部署的操作具有更低的延迟和更高的吞吐量。此示例说明如何自定义服务器选择算法以仅考虑在 localhost 上运行的服务器。
编写谓词函数
谓词函数必须满足以下条件:
接受对
ServerInfo对象的引用作为参数返回一个布尔值,表示服务器是否适合选择
不创建或修改任何
ServerInfo对象
以下示例定义了一个谓词,优先选择托管解决为 localhost 的服务器:
let prefer_localhost = Arc::new(|server_info: &ServerInfo| { matches!( server_info.address(), ServerAddress::Tcp { host, .. } if host == "localhost" ) });
处理没有服务器匹配的情况
如果谓词为每个可用服务器返回 false,驾驶员无法选择服务器。在这种情况下,操作失败并返回服务器选择超时错误,指示没有可用的服务器适合指定的条件。
为避免出现这种结果,请确保您的谓词在正常情况下至少匹配一台服务器,或者处理应用程序代码中的服务器选择错误,并在必要时使用限制性较低的 SelectionCriteria 进行重试。
在连接选项中使用谓词
要使用谓词进行服务器选择,请在创建客户端时将其传递给 selection_criteria 选项。选择 :guilabel:Asynchronous 或 :guilabel:Synchronous标签页,查看每个运行时的相应代码:
let prefer_localhost = Arc::new(|server_info: &ServerInfo| { matches!( server_info.address(), ServerAddress::Tcp { host, .. } if host == "localhost" ) }); let options = ClientOptions::builder() .hosts(vec![ServerAddress::Tcp { host: "<hostname>".to_string(), port: Some(27017), }]) .selection_criteria(SelectionCriteria::Predicate(prefer_localhost)) .build(); let client = Client::with_options(options)?;
let mut options = ClientOptions::parse( "mongodb://<db_username>:<db_password>@<hostname>:<port>", ) .await?; let prefer_localhost = Arc::new(|server_info: &ServerInfo| { matches!( server_info.address(), ServerAddress::Tcp { host, .. } if host == "localhost" ) }); options.selection_criteria = Some( SelectionCriteria::Predicate(prefer_localhost), ); let client = Client::with_options(options)?;
API 文档
有关自定义Rust驱动程序的服务器选择算法的更多信息,请参阅以下API文档: