Server Selector Example¶
Users can exert fine-grained control over the server selection algorithm
by setting the server_selector option on the
to an appropriate callable. This example shows how to use this functionality
to prefer servers running on
Use of custom server selector functions is a power user feature. Misusing custom server selectors can have unintended consequences such as degraded read/write performance.
Example: Selecting Servers Running on
To start, we need to write the server selector function that will be used.
The server selector function should accept a list of
ServerDescription objects and return a
list of server descriptions that are suitable for the read or write operation.
A server selector must not create or modify
ServerDescription objects, and must return
the selected instances unchanged.
In this example, we write a server selector that prioritizes servers running on
localhost. This can be desirable when using a sharded cluster with multiple
mongos, as locally run queries are likely to see lower latency and higher
throughput. Please note, however, that it is highly dependent on the
application if preferring
localhost is beneficial or not.
In addition to comparing the hostname with
localhost, our server selector
function accounts for the edge case when no servers are running on
localhost. In this case, we allow the default server selection logic to
prevail by passing through the received server description list unchanged.
Failure to do this would render the client unable to communicate with MongoDB
in the event that no servers were running on
The described server selection logic is implemented in the following server selector function:
>>> def server_selector(server_descriptions): ... servers = [ ... server for server in server_descriptions ... if server.address == 'localhost' ... ] ... if not servers: ... return server_descriptions ... return servers
Finally, we can create a
MongoClient instance with this
>>> client = MongoClient(server_selector=server_selector)
Server Selection Process¶
This section dives deeper into the server selection process for reads and writes. In the case of a write, the driver performs the following operations (in order) during the selection process:
Select all writeable servers from the list of known hosts. For a replica set this is the primary, while for a sharded cluster this is all the known mongoses.
Apply the user-defined server selector function. Note that the custom server selector is not called if there are no servers left from the previous filtering stage.
localThresholdMSsetting to the list of remaining hosts. This whittles the host list down to only contain servers whose latency is at most
localThresholdMSmilliseconds higher than the lowest observed latency.
Select a server at random from the remaining host list. The desired operation is then performed against the selected server.
In the case of reads the process is identical except for the first step.
Here, instead of selecting all writeable servers, we select all servers
matching the user’s
ReadPreference from the
list of known hosts. As an example, for a 3-member replica set with a
Secondary read preference, we would select
all available secondaries.