1- .. uses server-selection.rst
2-
31.. _pymongo-server-selection:
42
5- ================
6- Server Selection
7- ================
3+ ==========================
4+ Customize Server Selection
5+ ==========================
86
97.. contents:: On this page
108 :local:
@@ -17,88 +15,119 @@ Server Selection
1715 :values: reference
1816
1917.. meta::
20- :keywords: code example
18+ :keywords: code example, read preference, write
19+
20+ Overview
21+ --------
22+
23+ All MongoDB drivers follow a defined algorithm when selecting a server to read or write
24+ from. By using the ``server_selector`` property of ``MongoClient``, you can customize this
25+ algorithm to choose the server that works best for your application.
26+
27+ .. important::
28+
29+ Customizing the server-selection algorithm can have unintended consequences,
30+ such as degraded read or write performance.
31+
32+ Customized Selection Algorithm
33+ ------------------------------
34+
35+ When {+driver-short+} executes a read operation, it performs the following steps,
36+ in order, to select a MongoDB deployment:
2137
22- Users can exert fine-grained control over the :manual:`Server Selection
23- Algorithm </core/read-preference-mechanics/>` by setting the ``server_selector``
24- option on the ``~pymongo.MongoClient`` to an appropriate callable. This guide
25- shows you how to use this functionality to prefer servers running on ``localhost``.
38+ 1. From the list of known servers, {+driver-short+} selects all servers
39+ that match the active read preference.
2640
27- .. warning::
41+ #. If at least one readable server exists, {+driver-short+} calls the user-defined
42+ server-selector function and passes in the list from the previous step.
2843
29- Use of custom server selector functions is a power-user feature. Misusing
30- custom server selectors can have unintended consequences, such as degraded
31- read or write performance.
44+ #. {+driver-short+} applies the ``localThresholdMS`` connection setting to the list of
45+ servers returned from the function.
3246
33- Example: Selecting Servers Running on ``localhost``
34- ---------------------------------------------------
47+ #. {+driver-short+} selects a server at random from the servers still on the list and
48+ executes the operation against this server.
3549
36- First, write the server selector function.
37- The server selector function should accept a list of
38- ``~pymongo.server_description.ServerDescription`` objects, and return a
39- list of server descriptions that are suitable for the read or write operation.
40- A server selector must not create or modify
41- ``~pymongo.server_description.ServerDescription`` objects, and must return
42- the selected instances unchanged.
50+ When {+driver-short+} executes a write operation, it begins by selecting all writeable
51+ servers, not just those that match the active read preference. The remaining steps are
52+ identical.
4353
44- This example shows a server selector that prioritizes servers running on
45- ``localhost``. This can be desirable when using a sharded cluster with multiple
46- ``mongos`` servers, because locally run queries usually have lower latency and higher
47- throughput. However, the benefit of preferring ``localhost`` is highly dependent on the
48- application.
54+ To learn more about the default server-selection algorithm, which the driver follows
55+ when you don't use the ``server_selector`` argument, see
56+ :manual:`Server Selection Algorithm </core/read-preference-mechanics/>` in the
57+ MongoDB Server manual.
4958
50- In addition to comparing the hostname with ``localhost``, the server selector
51- function accounts for the edge case when no servers are running on
52- ``localhost``. In this case, the default server selection logic
53- prevails by returning the received server description list unchanged.
54- Failure to do this renders the client unable to communicate with MongoDB
55- if no servers are running on ``localhost``.
59+ Example: Select Servers on ``localhost``
60+ ----------------------------------------
5661
57- The following example implements the server selection logic:
62+ When using a sharded cluster with multiple ``mongos`` servers, you might want to prefer
63+ deployments running on ``localhost``. Operations against these deployments
64+ usually have lower latency and higher throughput.
65+ This example shows how to customize the server-selection algorithm to favor
66+ servers running on ``localhost``.
67+
68+ First, write a Python function to select your preferred servers.
69+ The server-selection function must meet the following criteria:
70+
71+ - Accepts a list of ``ServerDescription`` objects as a parameter
72+ - Returns the list of ``ServerDescription`` objects suitable for the read or write operation
73+ - Doesn't create or modify any ``ServerDescription`` objects
74+
75+ The following example defines a function named ``prefer_local`` that accepts and returns a list of
76+ ``ServerDescription`` objects:
5877
5978.. code-block:: python
79+ :emphasize-lines: 1,3
80+
81+ def prefer_local(server_descriptions):
82+ ...
83+ return servers # list containing preferred servers
84+
85+ Next, implement your server-selection logic in the function body. You can use any
86+ property defined in the ``ServerDescription`` class to select your preferred servers.
87+ To return only MongoDB deployments running on ``localhost``, this example loops on the
88+ servers in ``server_descriptions`` and checks the ``address`` property of each server
89+ for the value ``"localhost"``:
6090
61- >>> def server_selector(server_descriptions):
62- ... servers = [
63- ... server for server in server_descriptions if server.address[0] == "localhost"
64- ... ]
65- ... if not servers:
66- ... return server_descriptions
67- ... return servers
68- ...
91+ .. code-block:: python
92+ :emphasize-lines: 2-4
93+
94+ def prefer_local(server_descriptions):
95+ servers = [
96+ server for server in server_descriptions if server.address[0] == "localhost"
97+ ]
98+ return servers
99+
100+ Next, consider the case when your algorithm finds no matching servers. If your function
101+ returns an empty list, your application can't communicate with MongoDB. Therefore,
102+ return a list containing at least one ``ServerDescription`` object from your function.
69103
70- Finally, create a ``~pymongo.MongoClient `` instance with the
71- server selector :
104+ In this example, if no matching server is found, the ``prefer_local `` function returns
105+ the list of servers originally passed as an argument :
72106
73107.. code-block:: python
108+ :emphasize-lines: 6-7
74109
75- >>> client = MongoClient(server_selector=server_selector)
110+ def prefer_local(server_descriptions):
111+ servers = [
112+ server for server in server_descriptions if server.address[0] == "localhost"
113+ ]
76114
77- Server Selection Process
78- ------------------------
115+ if not servers:
116+ return server_descriptions
117+ return servers
79118
80- This section describes the server selection process for reads and
81- writes. For writes, the driver performs the following operations, in order,
82- during the selection process:
119+ Finally, instruct {+driver-short+} to use your function. To do so, call the ``MongoClient``
120+ constructor and pass the ``server_selector`` argument with your function name as the value:
83121
84- 1. Select all writeable servers from the list of known hosts. For a replica set,
85- the writeable server is the primary. For a sharded cluster, the
86- writeable servers are all the known ``mongos`` servers.
122+ .. code-block:: python
87123
88- #. Apply the user-defined server selector function. The custom server
89- selector is **not** called if there are no servers left from the previous
90- filtering stage.
124+ client = MongoClient(server_selector=prefer_local)
91125
92- #. Apply the ``localThresholdMS`` setting to the list of remaining hosts. This
93- whittles the host list down to contain only servers whose latency is at most
94- ``localThresholdMS`` milliseconds higher than the lowest observed latency.
126+ API Documentation
127+ -----------------
95128
96- #. Select a server at random from the remaining host list. The appropriate
97- operation is then performed against the selected server.
129+ For more information about customizing {+driver-short+}'s server-selection algorithm,
130+ see the following API documentation:
98131
99- For reads, the process is identical, except for the first step.
100- Instead of selecting all writeable servers, the driver selects all servers from the
101- list of known hosts that match the user's
102- ``~pymongo.read_preferences.ReadPreference``. For example, for a 3-member
103- replica set with a ``~pymongo.read_preferences.Secondary`` read preference,
104- the driver selects all available secondaries.
132+ - `MongoClient <{+api-root+}pymongo/mongo_client.html#pymongo.mongo_client.MongoClient>`__
133+ - `ServerDescription <{+api-root+}pymongo/server_description.html#pymongo.server_description.ServerDescription>`__
0 commit comments