1
- .. uses server-selection.rst
2
-
3
1
.. _pymongo-server-selection:
4
2
5
- ================
6
- Server Selection
7
- ================
3
+ ==========================
4
+ Customize Server Selection
5
+ ==========================
8
6
9
7
.. contents:: On this page
10
8
:local:
@@ -17,88 +15,119 @@ Server Selection
17
15
:values: reference
18
16
19
17
.. 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:
21
37
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.
26
40
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.
28
43
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.
32
46
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.
35
49
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.
43
53
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.
49
58
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
+ ----------------------------------------
56
61
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:
58
77
59
78
.. 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"``:
60
90
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.
69
103
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 :
72
106
73
107
.. code-block:: python
108
+ :emphasize-lines: 6-7
74
109
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
+ ]
76
114
77
- Server Selection Process
78
- ------------------------
115
+ if not servers:
116
+ return server_descriptions
117
+ return servers
79
118
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:
83
121
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
87
123
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)
91
125
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
+ -----------------
95
128
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:
98
131
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