Overview
所有MongoDB驱动程序在选择要读取或写入的服务器时都遵循定义的算法。通过使用 MongoClient
对象的 ClusterConfigurator
属性,您可以自定义此算法以选择最适合您的应用程序的服务器。
重要
自定义服务器选择算法可能会产生意想不到的后果,例如读取或写入性能下降。
默认算法
当.NET/ C#驱动程序执行读取操作时,它会按顺序执行以下步骤,以选择MongoDB 部署:
从已知服务器列表中选择与主动读取偏好(read preference)匹配的所有服务器。
如果至少存在一个可读服务器,驾驶员将调用用户定义的服务器选择器函数并传入上一步中的列表。
将
LocalThreshold
连接设置应用于从该函数返回的服务器列表。从仍在列表中的服务器中随机选择一个服务器,并对该服务器执行操作。
当.NET/ C#驱动程序执行写入操作时,它首先选择所有可写入的服务器,而不仅仅是那些与活动读取偏好(read preference)匹配的服务器。其余步骤相同。
要学习;了解默认服务器选择算法(在您未指定任何自定义服务器选择逻辑时驾驶员遵循的算法)的更多信息,请参阅MongoDB Server手册中的服务器选择算法。
指定其他服务器选择算法
您可以通过将服务器选择器类的实例传递给 ClusterConfigurator
的 PreServerSelector
或 PostServerSelector
属性来指定不同的服务器选择逻辑。PreServerSelector
属性指定在标准服务器选择逻辑运行之前运行的服务器选择器,而 PostServerSelector
属性指定在标准服务器选择逻辑运行之后运行的服务器选择器。然后,您可以在创建 MongoClient
实例时将 ClusterConfigurator
实例传递给 MongoClientSettings
对象,以应用自定义服务器选择逻辑。
下表列出了您可以传递给 ClusterConfigurator
属性的不同类型的服务器选择器:
服务器选择器 | 说明 |
---|---|
| 根据多个部分选择器选择服务器 |
| 封装委托服务器选择器 |
| 根据端点选择服务器 |
| 选择在可接受延迟范围内的服务器 |
| 根据要降低优先级的服务器集合选择一台服务器 |
| 选择一个随机服务器 |
| 根据指定的读取偏好(read preference)选择服务器 |
以下示例指示 MongoClient
在标准服务器选择逻辑运行之前使用 RandomServerSelector
类随机选择一个服务器:
var settings = MongoClientSettings.FromConnectionString("<connection string>"); var clusterConfigurator = builder => { builder.ConfigureCluster(c => c.With(PreServerSelector: new RandomServerSelector())); }; settings.ClusterConfigurator = clusterConfigurator; var client = new MongoClient(settings);
要学习;了解有关不同服务器选择器类的更多信息,请参阅 ServerSelectors API文档。
实施自定义服务器选择逻辑
您可以通过创建一个类来继承 IServerSelector
接口并覆盖 SelectServers()
方法,实现自己的自定义服务器选择逻辑。以下示例显示了一个简单的自定义服务器选择类,该类选择 ServerType
为 ServerType.ReplicaSetSecondary
的服务器:
public class CustomServerSelector : IServerSelector { public IEnumerable<ServerDescription> SelectServers(ClusterDescription cluster, IEnumerable<ServerDescription> servers) { return servers.Where(server => server.Type == ServerType.ReplicaSetSecondary); } }
然后,您可以将此类的实例传递给 ClusterConfigurator
实例的 PreServerSelector
或 PostServerSelector
属性,如指定其他服务器选择算法部分所示。
使用设置配置服务器选择
您可以在 MongoClient
对象或连接 URI 中指定以下服务器选择设置:
设置 | 说明 | |||
---|---|---|---|---|
| The latency window for server eligibility. If a server's round trip takes longer than the fastest server's round-trip time plus this value, the server isn't eligible for selection. Data Type: TimeSpan Default: 15 milliseconds Connection URI Example: localThresholdMS=0 | |||
| The client's default read-preference settings. MaxStaleness represents thelongest replication lag (in real time) that a secondary can experience and still be eligible for server selection. Specifying -1 means no maximum.See read preference for more information. Data Type: ReadPreference Default: ReadPreference.Primary Connection URI Example:
| |||
| The length of time the driver tries to select a server before timing out. Data Type: TimeSpan Default: 30 seconds Connection URI Example: serverSelectionTimeoutMS=15000 |
故障排除
驱动程序在服务器选择期间抛出超时
每个驾驶员操作都要求您选择满足服务器选择条件的服务器。如果未在服务器选择超时时间内选择适当的服务器,驾驶员将引发服务器选择超时异常。该异常看起来类似于以下内容:
A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. Client view of cluster state is { ClusterId : "1", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/localhost:27017" }", EndPoint: "Unspecified/localhost:27017", ReasonChanged: "Heartbeat", State: "Disconnected", ServerVersion: , TopologyVersion: , Type: "Unknown", HeartbeatException: "<exception details>" }] }.
错误信息由多个部分组成:
服务器选择超时(30000 毫秒)。
考虑的服务器选择器(
CompositeServerSelector
,包含AreSessionsSupportedServerSelector
、LatencyLimitingServerSelector
和OperationsCountServerSelector
)。驱动程序对集群拓扑的当前视图。驱动程序感知到的服务器列表是该视图的关键部分。每个服务器描述都包含其当前状态的详尽描述,包括端点信息、服务器版本、服务器类型及其当前健康状态。如果服务器在报告健康状况时遇到问题,
HeartbeatException
包含自上次失败的心跳以来的异常。分析每个集群节点上的HeartbeatException
可以帮助诊断大多数服务器选择问题。以下是常见的心跳异常:No connection could be made because the target machine actively refused it
:驾驶员看不到此集群节点。这可能是因为集群节点已崩溃,防火墙阻止网络流量到达集群节点或端口,或者其他一些网络错误阻止流量成功路由到集群节点。Attempted to read past the end of the stream
:由于网络错误、防火墙配置错误或其他网络问题,导致驾驶员无法连接到集群节点时,会出现此错误。要解决此异常,请确保所有集群节点均可访问。当客户端计算机的IP解决未配置在Atlas IP 访问列表中时,通常会出现此错误,您可以在Atlas项目的 Network Access标签页页下找到该列表。The remote certificate is invalid according to the validation procedure
:该错误通常表示 TLS/SSL 相关问题,如证书过期/无效或根 CA 不可信。您可以使用openssl s_client
等工具来调试与 TLS/SSL 相关的证书问题。
API 文档
要学习;了解有关本指南中使用的类和方法的更多信息,请参阅以下API文档: