|
1 |
| -.. TODO: Server Selection page |
2 |
| - |
3 |
| -Why Does the Driver Throw a Timeout During Server Selection? |
4 |
| ------------------------------------------------------------- |
5 |
| - |
6 |
| -Each driver operation requires that you choose a healthy server |
7 |
| -satisfying the :manual:`server selection criteria |
8 |
| -</core/read-preference-mechanics>`. If you do not select an appropriate |
9 |
| -server within the `server selection timeout <{+new-api-root+}/MongoDB.Driver.Legacy/MongoDB.Driver.MongoServerSettings.ServerSelectionTimeout.html>`__, the driver throws a |
10 |
| -server selection timeout exception. The exception looks similar to the |
11 |
| -following: |
12 |
| - |
13 |
| -.. code-block:: none |
14 |
| - |
15 |
| - A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. |
16 |
| - Client view of cluster state is |
17 |
| - { |
18 |
| - ClusterId : "1", |
19 |
| - Type : "Unknown", |
20 |
| - State : "Disconnected", |
21 |
| - Servers : |
22 |
| - [{ |
23 |
| - ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/localhost:27017" }", |
24 |
| - EndPoint: "Unspecified/localhost:27017", |
25 |
| - ReasonChanged: "Heartbeat", |
26 |
| - State: "Disconnected", |
27 |
| - ServerVersion: , |
28 |
| - TopologyVersion: , |
29 |
| - Type: "Unknown", |
30 |
| - HeartbeatException: "<exception details>" |
31 |
| - }] |
32 |
| - }. |
33 |
| - |
34 |
| -The error message consists of multiple parts: |
35 |
| - |
36 |
| -1. The server selection timeout (30000 ms). |
37 |
| -#. The server selectors considered (``CompositeServerSelector`` |
38 |
| - containing ``AreSessionsSupportedServerSelector``, |
39 |
| - ``LatencyLimitingServerSelector``, and |
40 |
| - ``OperationsCountServerSelector``). |
41 |
| -#. The driver’s current view of the cluster topology. The list of |
42 |
| - servers that the driver is aware of is a key part of this view. Each |
43 |
| - server description contains an exhaustive description of its current |
44 |
| - state including information about an endpoint, a server version, a |
45 |
| - server type, and its current health state. If the server encounters issues in |
46 |
| - reporting its health, ``HeartbeatException`` contains the exception from the |
47 |
| - last failed heartbeat. Analyzing the ``HeartbeatException`` on each |
48 |
| - cluster node can assist in diagnosing most server selection issues. |
49 |
| - The following heartbeat exceptions are common: |
50 |
| - |
51 |
| - * ``No connection could be made because the target machine actively |
52 |
| - refused it``: The driver cannot see this cluster node. This can be |
53 |
| - because the cluster node has crashed, a firewall is preventing |
54 |
| - network traffic from reaching the cluster node or port, or some other |
55 |
| - network error is preventing traffic from being successfully routed to |
56 |
| - the cluster node. |
57 |
| - * ``Attempted to read past the end of the stream``: This error |
58 |
| - happens when the driver cannot connect to the cluster nodes due to a |
59 |
| - network error, misconfigured firewall, or other network issue. To |
60 |
| - address this exception, ensure that all cluster nodes are reachable. |
61 |
| - This error commonly occurs when the client machine’s IP address is |
62 |
| - not configured in the Atlas IPs Access List, which can be found under |
63 |
| - the :guilabel:`Network Access` tab for your Atlas Project. |
64 |
| - * ``The remote certificate is invalid according to the validation |
65 |
| - procedure``: This error typically indicates a TLS/SSL-related problem |
66 |
| - such as an expired/invalid certificate or an untrusted root CA. You |
67 |
| - can use tools like ``openssl s_client`` to debug TLS/SSL-related |
68 |
| - certificate problems. |
| 1 | +.. _csharp-server-selection: |
| 2 | + |
| 3 | +========================== |
| 4 | +Customize Server Selection |
| 5 | +========================== |
| 6 | + |
| 7 | +.. contents:: On this page |
| 8 | + :local: |
| 9 | + :backlinks: none |
| 10 | + :depth: 1 |
| 11 | + :class: singlecol |
| 12 | + |
| 13 | +.. facet:: |
| 14 | + :name: genre |
| 15 | + :values: reference |
| 16 | + |
| 17 | +.. meta:: |
| 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 ``ClusterConfigurator`` property of a ``MongoClient`` object, you can |
| 25 | +customize this algorithm to choose the server that works best for your application. |
| 26 | + |
| 27 | +.. important:: |
| 28 | + |
| 29 | + Customizing the server selection algorithm might have unintended consequences, |
| 30 | + such as degraded read or write performance. |
| 31 | + |
| 32 | +Default Algorithm |
| 33 | +----------------- |
| 34 | + |
| 35 | +When the {+driver-short+} executes a read operation, it performs the following steps, |
| 36 | +in order, to select a MongoDB deployment: |
| 37 | + |
| 38 | +1. Selects all servers that match the active read preference from the list of known servers. |
| 39 | + |
| 40 | +#. If at least one readable server exists, the driver calls the user-defined |
| 41 | + server-selector function and passes in the list from the previous step. |
| 42 | + |
| 43 | +#. Applies the ``LocalThreshold`` connection setting to the list of |
| 44 | + servers returned from the function. |
| 45 | + |
| 46 | +#. Selects a server at random from the servers still on the list and |
| 47 | + executes the operation against this server. |
| 48 | + |
| 49 | +When the {+driver-short+} executes a write operation, it begins by selecting all writeable |
| 50 | +servers, not just those that match the active read preference. The remaining steps are |
| 51 | +identical. |
| 52 | + |
| 53 | +To learn more about the default server selection algorithm, which the driver follows |
| 54 | +when you don't specify any custom server selection logic, see |
| 55 | +:manual:`Server Selection Algorithm </core/read-preference-mechanics/>` in the |
| 56 | +{+mdb-server+} manual. |
| 57 | + |
| 58 | +.. _csharp-server-selection-algorithm: |
| 59 | + |
| 60 | +Specifying Other Server Selection Algorithms |
| 61 | +-------------------------------------------- |
| 62 | + |
| 63 | +You can specify different server selection logic by passing an instance of a server selector |
| 64 | +class to the ``PreServerSelector`` or ``PostServerSelector`` property of the ``ClusterConfigurator``. The |
| 65 | +``PreServerSelector`` property specifies a server selector that runs before the |
| 66 | +standard server selection logic runs, while the ``PostServerSelector`` property |
| 67 | +specifies a server selector that runs after standard server selection logic runs. You can |
| 68 | +then pass your ``ClusterConfigurator`` instance to the ``MongoClientSettings`` object when you create a |
| 69 | +``MongoClient`` instance to apply your custom server selection logic. |
| 70 | + |
| 71 | +The following table lists the different types of server selectors you can pass to the |
| 72 | +``ClusterConfigurator`` property: |
| 73 | + |
| 74 | +.. list-table:: |
| 75 | + :header-rows: 1 |
| 76 | + :widths: 40 60 |
| 77 | + |
| 78 | + * - Server Selector |
| 79 | + - Description |
| 80 | + |
| 81 | + * - ``CompositeServerSelector`` |
| 82 | + - Selects servers based on multiple partial selectors |
| 83 | + |
| 84 | + * - ``DelegateServerSelector`` |
| 85 | + - Wraps a delegate server selector |
| 86 | + |
| 87 | + * - ``EndPointServerSelector`` |
| 88 | + - Selects servers based on their endpoint |
| 89 | + |
| 90 | + * - ``LatencyLimitingServerSelector`` |
| 91 | + - Selects servers within an acceptable latency range |
| 92 | + |
| 93 | + * - ``PriorityServerSelector`` |
| 94 | + - Selects a server based on a collection of servers to deprioritize |
| 95 | + |
| 96 | + * - ``RandomServerSelector`` |
| 97 | + - Selects a random server |
| 98 | + |
| 99 | + * - ``ReadPreferenceServerSelector`` |
| 100 | + - Selects servers based on a specified read preference |
| 101 | + |
| 102 | +The following example instructs a ``MongoClient`` to use the ``RandomServerSelector`` |
| 103 | +class to select a server at random before the standard server selection logic runs: |
| 104 | + |
| 105 | +.. literalinclude:: /includes/fundamentals/code-examples/connection/ServerSelection.cs |
| 106 | + :start-after: start-server-selector |
| 107 | + :end-before: end-server-selector |
| 108 | + :language: csharp |
| 109 | + :dedent: |
| 110 | + |
| 111 | +To learn more about the different server selector classes, see the |
| 112 | +`ServerSelectors API documentation <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Clusters.ServerSelectors.html>`__. |
| 113 | + |
| 114 | +Implementing Custom Server Selection Logic |
| 115 | +------------------------------------------ |
| 116 | + |
| 117 | +You can implement your own custom server selection logic by creating a class that |
| 118 | +inherits from the ``IServerSelector`` interface and overrides the |
| 119 | +``SelectServers()`` method. The following example shows a simple custom server |
| 120 | +selection class that selects servers with a ``ServerType`` of |
| 121 | +``ServerType.ReplicaSetSecondary``: |
| 122 | + |
| 123 | +.. literalinclude:: /includes/fundamentals/code-examples/connection/ServerSelection.cs |
| 124 | + :start-after: start-custom-class |
| 125 | + :end-before: end-custom-class |
| 126 | + :language: csharp |
| 127 | + :dedent: |
| 128 | + |
| 129 | +You can then pass an instance of this class to the ``PreServerSelector`` or |
| 130 | +``PostServerSelector`` property of a ``ClusterConfigurator`` instance, as shown in the |
| 131 | +:ref:`csharp-server-selection-algorithm` section. |
| 132 | + |
| 133 | +Using Settings to Configure Server Selection |
| 134 | +-------------------------------------------- |
| 135 | + |
| 136 | +You can specify the following server selection settings in your ``MongoClient`` object or |
| 137 | +in your connection URI: |
| 138 | + |
| 139 | +.. list-table:: |
| 140 | + :widths: 30 70 |
| 141 | + :header-rows: 1 |
| 142 | + |
| 143 | + * - Setting |
| 144 | + - Description |
| 145 | + |
| 146 | + * - ``LocalThreshold`` |
| 147 | + - | The latency window for server eligibility. If a server's round trip takes longer |
| 148 | + | than the fastest server's round-trip time plus this value, the server isn't |
| 149 | + | eligible for selection. |
| 150 | + | |
| 151 | + | **Data Type**: ``TimeSpan`` |
| 152 | + | **Default**: 15 milliseconds |
| 153 | + | **Connection URI Example**: ``localThresholdMS=0`` |
| 154 | + |
| 155 | + * - ``ReadPreference`` |
| 156 | + - | The client's default read-preference settings. ``MaxStaleness`` represents the |
| 157 | + | longest replication lag (in real time) that a secondary can experience and |
| 158 | + | still be eligible for server selection. Specifying ``-1`` means no maximum. |
| 159 | + | See :ref:`read preference <read-preference>` for more information. |
| 160 | + | |
| 161 | + | **Data Type**: `ReadPreference <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.ReadPreference.html>`__ |
| 162 | + | **Default**: ``ReadPreference.Primary`` |
| 163 | + | **Connection URI Example**: |
| 164 | + |
| 165 | + .. code-block:: none |
| 166 | + :copyable: false |
| 167 | + |
| 168 | + readPreference=primaryPreferred |
| 169 | + &maxStalenessSeconds=90 |
| 170 | + &readPreferenceTags=dc:ny,rack:1 |
| 171 | + |
| 172 | + * - ``ServerSelectionTimeout`` |
| 173 | + - | The length of time the driver tries to select a server before timing out. |
| 174 | + | |
| 175 | + | **Data Type**: ``TimeSpan`` |
| 176 | + | **Default**: 30 seconds |
| 177 | + | **Connection URI Example**: ``serverSelectionTimeoutMS=15000`` |
| 178 | + |
| 179 | +Troubleshooting |
| 180 | +--------------- |
| 181 | + |
| 182 | +.. include:: /includes/troubleshooting/server-selection-timeout.rst |
| 183 | + |
| 184 | +API Documentation |
| 185 | +----------------- |
| 186 | + |
| 187 | +To learn more about the classes and methods used in this guide, see the following API |
| 188 | +documentation: |
| 189 | + |
| 190 | +- `MongoClient <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClient.html>`__ |
| 191 | +- `MongoClientSettings <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClientSettings.html>`__ |
| 192 | +- `ClusterConfigurator <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.MongoClientSettings.ClusterConfigurator.html>`__ |
| 193 | +- `ServerSelectors <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Clusters.ServerSelectors.html>`__ |
| 194 | +- `IServerSelector <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Clusters.ServerSelectors.IServerSelector.html>`__ |
| 195 | +- `SelectServer() <{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Core.Clusters.ServerSelectors.IServerSelector.SelectServers.html>`__ |
0 commit comments