Skip to content

Commit 497238f

Browse files
p-mongop
andauthored
RUBY-2647 Implement connect=load_balanced
(#2256) * RUBY-2647 Implement connect=load_balanced * lb server selection does not require working connections * update shared Co-authored-by: Oleg Pudeyev <[email protected]>
1 parent db972a3 commit 497238f

File tree

1 file changed

+204
-43
lines changed

1 file changed

+204
-43
lines changed

source/reference/create-client.txt

Lines changed: 204 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -111,87 +111,228 @@ their stated purposes:
111111
Connection Types
112112
================
113113

114-
Direct Connection
115-
-----------------
116-
117-
If the deployment is a replica set, the driver will by default discover all
118-
members of the replica set given the address of any one member, and will
119-
dispatch operations to the appropriate member (for example, writes would be
120-
dispatched to the primary).
121-
122-
To force all operations to be performed on the designated server, specify the
123-
``direct_connection`` option:
114+
The driver will, by default, discover the type of deployment it is instructed
115+
to connect to (except for load-balanced deployments)
116+
and behave in the manner that matches the deployment type.
117+
The subsections below describe how the driver behaves in each of the deployment
118+
types as well as how to force particular behavior, bypassing automatic
119+
deployment type detection.
120+
121+
Note that the detection of deployment type happens when the driver receives
122+
the first reply from any of the servers it is instructed to connect to
123+
(unless the load-balancing mode is requested, see below). The driver will
124+
remain in the discovered or configured topology even if the underlying
125+
deployment is replaced by one of a different type. In particular, when
126+
replacing a replica set with a sharded cluster at the same address
127+
the client instance must be recreated (such as by restarting the application)
128+
for it to communicate with the sharded cluster.
129+
130+
Automatic discovery of load-balanced deployments is currently not supported.
131+
Load-balanced deployments will be treated as deployments of their underlying
132+
type, which would generally be sharded clusters. The driver will fail to
133+
correctly operate when treating a load-balanced deployment as a sharded
134+
cluster, therefore when the deployment is a load-balanced one the client
135+
must be explicitly configured to :ref:`connect to a load balancer
136+
<load-balancer-connection>`.
137+
138+
139+
Standalone Server Connection
140+
----------------------------
124141

125-
.. code-block:: ruby
142+
If the deployment is a single server, also known as a standalone deployment,
143+
all operations will be directed to the specified server.
126144

127-
Mongo::Client.new([ '1.2.3.4:27017' ], database: 'mydb', direct_connection: true)
145+
If the server is shut down and replaced by a replica set node, the driver
146+
will continue sending all operations to that node, even if the node is or
147+
becomes a secondary.
128148

129-
# Or using the URI syntax:
130-
Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?directConnection=true")
149+
To force a standalone connection, see the :ref:`direct connection
150+
<direct-connection>` section below.
131151

132152

133153
.. _connect-replica-set:
134154

135155
Replica Set Connection
136156
----------------------
137157

138-
To connect to a :manual:`replica set</replication/>` deployment managed by a
139-
service providing SRV URIs (such as MongoDB Atlas), connect to the URI:
158+
When connecting to a :manual:`replica set</replication/>`, it is sufficient
159+
to pass the address of any node in the replica set to the driver.
160+
The node does not have to be the primary and it may be a hidden node.
161+
The driver will then automatically discover the remaining nodes.
162+
163+
However, it is recommended to specify all nodes that are part of the
164+
replica set, so that in the event of one or more nodes being unavailable
165+
(for example, due to maintenance or reconfiguration) the driver can still
166+
connect to the replica set.
167+
168+
Replica set connection examples:
140169

141170
.. code-block:: ruby
142171

143-
Mongo::Client.new("mongodb+srv://username:[email protected]/test?w=majority")
172+
Mongo::Client.new([ '127.0.0.1:27017' ], database: 'mydb')
144173

145-
If not using SRV URIs, it is sufficient to pass the address of any node in the
146-
replica set to the driver; the driver will then automatically discover the
147-
remaining nodes. However, it is recommended to specify all nodes that are part
148-
of the replica set, so that in the event of one or more nodes being unavailable
149-
(for example, due to maintenance or reconfiguration) the driver can still
150-
connect to the replica set.
174+
Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27018' ], database: 'mydb')
175+
176+
# Or using the URI syntax:
177+
Mongo::Client.new("mongodb://127.0.0.1:27017,127.0.0.1:27018/mydb")
178+
179+
To make the driver verify the replica set name upon connection, pass it using
180+
the ``replica_set`` Ruby option or the ``replicaSet`` URI option:
151181

152182
.. code-block:: ruby
153183

154184
Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27018' ],
155-
:database => 'mydb', replica_set: 'myapp')
185+
database: 'mydb', replica_set: 'myapp')
156186

157187
# Or using the URI syntax:
158188
Mongo::Client.new("mongodb://127.0.0.1:27017,127.0.0.1:27018/mydb?replicaSet=myapp")
159189

190+
If the deployment is not a replica set or uses a different replica set name,
191+
all operations will fail (until the expected replica set is returned by
192+
the servers).
193+
194+
It is also possible to force a replica set connection without specifying
195+
the replica set name. Doing so is generally unnecessary and is deprecated:
196+
197+
.. code-block:: ruby
198+
199+
Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27018' ],
200+
database: 'mydb', connect: :replica_set)
201+
202+
# Or using the URI syntax:
203+
Mongo::Client.new("mongodb://127.0.0.1:27017,127.0.0.1:27018/mydb?connect=replica_set")
204+
205+
To connect to a MongoDB Atlas cluster which is deployed as a replica set,
206+
connect to the URI:
207+
208+
.. code-block:: ruby
209+
210+
Mongo::Client.new("mongodb+srv://username:[email protected]/test?w=majority")
211+
212+
Please review the :ref:`SRV URI notes <srv-uri-notes>` if using SRV URIs.
213+
160214

161215
.. _connect-sharded-cluster:
162216

163217
Sharded Cluster Connection
164218
--------------------------
165219

166-
To connect to a :manual:`sharded cluster</sharding/>` deployment managed by a
167-
service providing SRV URIs (such as MongoDB Atlas), connect to the URI:
220+
To connect to a :manual:`sharded cluster</sharding/>` deployment, specify
221+
the addresses of the ``mongos`` routers:
222+
223+
.. code-block:: ruby
224+
225+
Mongo::Client.new([ '1.2.3.4:27017', '1.2.3.5:27017' ], database: 'mydb')
226+
227+
Mongo::Client.new("mongodb://1.2.3.4:27017,1.2.3.5:27017/mydb")
228+
229+
Note that unlike a replica set connection, you may choose to connect to a
230+
subset of the ``mongos`` routers that exist in the deployment. The driver
231+
will monitor each router and will use the ones that are available
232+
(i.e., the driver will generally handle individual routers becoming
233+
unavailable due to failures or maintenance). When specifying the list of
234+
routers explicitly, the driver will not discover remaining routers that
235+
may be configured and will not attempt to connect to them.
236+
237+
The driver will automatically balance the operation load among the routers
238+
it is aware of.
239+
240+
To connect to a MongoDB Atlas cluster which is deployed as a sharded cluster,
241+
connect to the URI:
168242

169243
.. code-block:: ruby
170244

171245
Mongo::Client.new("mongodb+srv://username:[email protected]/test?w=majority")
172246

173-
When the driver connects to a sharded cluster via an SRV URI, it will monitor
174-
the SRV records of the address specified in the URI for changes and will
175-
automatically add and remove ``mongos`` hosts to/from its list of servers as
176-
they are added and removed to/from the sharded cluster.
247+
When the driver connects to a sharded cluster via an SRV URI, it will
248+
periodically poll the SRV records of the address specified in the URI
249+
for changes and will automatically add and remove the ``mongos`` hosts
250+
to/from its list of servers as they are added and removed to/from the
251+
sharded cluster.
177252

178-
If not using SRV URIs, pass the addresses of one or more
179-
:manual:`mongos</reference/program/mongos/>` hosts. Unlike with
180-
replica set deployments, the driver is not able to discover all ``mongos``
181-
nodes in a sharded cluster when not using SRV URIs. It is not required that all
182-
``mongos`` node addresses are given to the driver - the driver will balance
183-
the operation load among the nodes it is given. Specifying more nodes will
184-
spread the operation load accordingly.
253+
To force a sharded cluster connection, use the ``connect: :sharded``
254+
option. Doing so is generally unnecessary and is deprecated:
185255

186256
.. code-block:: ruby
187257

188-
Mongo::Client.new([ '1.2.3.4:27017', '1.2.3.5:27017' ], :database => 'mydb')
258+
Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27018' ],
259+
database: 'mydb', connect: :sharded)
189260

190-
Mongo::Client.new("mongodb://1.2.3.4:27017,1.2.3.5:27017/mydb")
261+
# Or using the URI syntax:
262+
Mongo::Client.new("mongodb://127.0.0.1:27017,127.0.0.1:27018/mydb?connect=sharded")
191263

264+
Please review the :ref:`SRV URI notes <srv-uri-notes>` if using SRV URIs.
192265

193-
SRV URIs
194-
========
266+
267+
.. _direct-connection:
268+
269+
Direct Connection
270+
-----------------
271+
272+
To disable the deployment type discovery and force all operations to be
273+
performed on a particular server, specify the ``direct_connection`` option:
274+
275+
.. code-block:: ruby
276+
277+
Mongo::Client.new([ '1.2.3.4:27017' ], database: 'mydb', direct_connection: true)
278+
279+
# Or using the URI syntax:
280+
Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?directConnection=true")
281+
282+
Alternatively, the deprecated ``connect: :direct`` option is equivalent:
283+
284+
.. code-block:: ruby
285+
286+
Mongo::Client.new([ '1.2.3.4:27017' ], database: 'mydb', connect: :direct)
287+
288+
# Or using the URI syntax:
289+
Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?connect=direct")
290+
291+
The direct connection mode is most useful for performing operations on a
292+
particular replica set node, although it also permits the underlying server
293+
to change type (e.g. from a replica set node to a ``mongos`` router, or vice
294+
versa).
295+
296+
297+
.. _load-balancer-connection:
298+
299+
Load Balancer Connection
300+
------------------------
301+
302+
Unlike other deployment types, the driver does not currently automatically
303+
detect a load-balanced deployment.
304+
305+
To connect to a load balancer, specify the ``load_balanced: true`` Ruby option
306+
or the ``loadBalanced=true`` URI option:
307+
308+
.. code-block:: ruby
309+
310+
Mongo::Client.new([ '1.2.3.4:27017' ], database: 'mydb', load_balanced: true)
311+
312+
# Or using the URI syntax:
313+
Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?loadBalanced=true")
314+
315+
When using these options, if the specified server is not a load balancer,
316+
the client will fail all operations (until the server becomes a load balancer).
317+
318+
To treat the server as a load balancer even if it doesn't identify as such,
319+
use the ``connect: :load_balanced`` Ruby option or the ``connect=load_balanced``
320+
URI option:
321+
322+
.. code-block:: ruby
323+
324+
Mongo::Client.new([ '1.2.3.4:27017' ],
325+
database: 'mydb', load_balanced: true, connect: :load_balanced)
326+
327+
# Or using the URI syntax:
328+
Mongo::Client.new("mongodb://1.2.3.4:27017/mydb?loadBalanced=true&connect=load_balanced")
329+
330+
331+
332+
.. _srv-uri-notes:
333+
334+
SRV URI Notes
335+
=============
195336

196337
When the driver connects to a
197338
:manual:`mongodb+srv protocol <reference/connection-string/#dns-seedlist-connection-format>`
@@ -209,7 +350,18 @@ URI, keep in mind the following:
209350
2. The driver looks up URI options in the DNS TXT records corresponding to the
210351
SRV records. These options can be overridden by URI options specified in the
211352
URI and by Ruby options, in this order.
212-
3. If the topology of the constructed ``Client`` object is unknown or a
353+
3. Because the URI options are retrieved in a separate DNS query from the
354+
SRV lookup, in environments with unreliable network connectivity
355+
the URI option query may fail when the SRV lookup succeeds. Such a failure
356+
would cause the driver to use the wrong auth source leading to
357+
authentication failures. This can be worked around by explicitly specifying
358+
the auth source:
359+
360+
.. code-block:: ruby
361+
362+
Mongo::Client.new("mongodb+srv://username:[email protected]/test?w=majority&authSource=admin")
363+
364+
4. If the topology of the constructed ``Client`` object is unknown or a
213365
sharded cluster, the driver will begin monitoring the specified SRV DNS
214366
records for changes and will automatically update the list of servers in the
215367
cluster. The updates will stop if the topology becomes a single or a replica
@@ -327,7 +479,11 @@ Ruby Options
327479
* - ``:connect``
328480
- **Deprecated.** Disables deployment topology discovery normally
329481
performed by the dirver and forces the cluster topology to a specific
330-
type. Choices: ``:direct``, ``:replica_set`` or ``:sharded``.
482+
type. Valid values are ``:direct``, ``:load_balanced``,
483+
``:replica_set`` or ``:sharded``. If ``:load_balanced`` is used,
484+
the client will behave as if it is connected to a load balancer
485+
regardless of whether the server(s) it connects to advertise themselves
486+
as load balancers.
331487
- ``Symbol``
332488
- none
333489

@@ -768,6 +924,11 @@ URI options are explained in detail in the :manual:`Connection URI reference
768924
* - connect=String
769925
- ``:connect => Symbol``
770926

927+
The same values that the ``:connect`` Ruby option accepts are
928+
accepted here. For multi-word values, the values must be provided
929+
using underscores to separate the words, i.e.
930+
``connect=replica_set`` and ``connect=load_balanced``.
931+
771932
* - connectTimeoutMS=Integer
772933
- ``:connect_timeout => Float``
773934

0 commit comments

Comments
 (0)