Uploaded image for project: 'Java Driver'
  1. Java Driver
  2. JAVA-428

Support new ReadPreference semantics, deprecate SlaveOK



    • Type: New Feature
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.7
    • Component/s: None
    • Labels:
    • Backwards Compatibility:
      Minor Change


      Read Behavior

      Read Preference

      Each driver needs some way of setting this value.

      There are three read preferences:

      1. primary
      2. secondary
      3. [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.:


      As tags is an array and the other two are scalars, some langauges may need to handle this a little differently than others.


      Default. Sends all reads to primary.


      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.


      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.


          Issue Links



              brendan Brendan W. McAdams
              brendan Brendan W. McAdams
              1 Vote for this issue
              3 Start watching this issue