Read Behavior
Read Preference
Each driver needs some way of setting this value.
There are three read preferences:
- primary
- secondary
- [tag1, tag2, ..., tagN]
This document will use the names above, but these levels should be members of an enum or consts in your driver, e.g.:
ReadPreference.primary ReadPreference.secondary ReadPreference.tags
As tags is an array and the other two are scalars, some langauges may need to handle this a little differently than others.
setReadPreference(primary)
Default. Sends all reads to primary.
setReadPreference(secondary)
Implementation detail: automatically create a set of buckets that grow exponentially. Pick secondaries randomly from nodes in the nearest bucket. Use the "ping" command for testing ping times. Do this every five seconds, using a separate socket, with very low timeouts.
Bucket | Number of nodes |
---|---|
1 (0 - 10ms) | 2 |
2 (10 - 100ms) | 1 |
3 (100 - 1000ms) | 3 |
In this case, we'd pick randomly from the nodes in the 0-10ms bucket. If users need more sophisticated read preferences, let them use tags.
If no secondary is available, fall back on reading from the primary.
In Java, we'll probably want to add a ReadPreference class (like WriteConcern).
Eventually, there should be a "secondaryOnly" option, too, that will only read from a secondary and return an error if only the primary is available. This is not necessary for 2.0, though.
setReadPreference({"server" : "A", "dc" : "ny", "type" : "backup"})
Attempt to read from a server tagged with "server" : "A". If there are no readable servers with "server" : "A", attempt to read from servers with "dc" : "ny", etc.
If there are multiple servers matching a tag, choose a secondary using the same bucket strategy as described in the setReadPreference(secondary) section above.
Read-by-tags Implementation
On connection, drivers should call isMaster, which will include a field containing all the tags for the node in question.
{ tags : {tag1 : loc1, tag2 : loc2, ..., tagP : locP} }
Error checking
The drivers should check that the tags actually match potentially readable servers in setReadPreference. If the only tag the driver got from the database was "foo", setReadPreference should not allow people to use "bar", "baz", "bat", etc. as tags.
Setting read preference with sharding
This will probably be a meta option (e.g., {$tags : {"x":"foo","y":"bar","z":"baz"}, $query : {...}}, but this has not been decided yet.
Connections
Drivers can connect to a single node or to a replica set.
Connecting to a single node
Drivers should provide the option to connect to a single node by providing a simple Connection class.
Connecting to a replica set
Driver should connect to a replica set via a specific ReplicaSetConnection class. Users should be able to connect to a replica set by providing one or more seed nodes. The replica set name should be required.
Replica set connection behavior
When readPreference is set to "secondary": if no primary exists, but the connection succeeds, then the connection becomes read-only until a primary comes back online. In this case, any attempt to write, particularly a non-safe write, must raise an exception.
If readPreference is set to a set of tags and no primary exists, then the connection becomes read-only. In this case, any attempt to write, particularly a non-safe write, must raise an exception.
- is depended on by
-
JAVA-457 Reenable Read By Tags when mongos also supports it
- Closed