Java Driver
  1. Java Driver
  2. JAVA-428

Support new ReadPreference semantics, deprecate SlaveOK

    Details

    • Type: New Feature New Feature
    • Status: Resolved Resolved
    • Priority: Major - P3 Major - P3
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.7
    • Component/s: None
    • Labels:
    • Backward Breaking:
      Sometimes
    • # Replies:
      16
    • Last comment by Customer:
      false

      Description

      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.:

      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.

        Issue Links

          Activity

          Hide
          auto
          added a comment -

          Author:

          {u'login': u'agirbal', u'name': u'agirbal', u'email': u'antoine@10gen.com'}

          Message: JAVA-428: Support new ReadPreference semantics, deprecate SlaveOK
          Branch: master
          https://github.com/mongodb/mongo-java-driver/commit/3e96c2f055df6b47d7259a4eb7b142e5435d3a01

          Show
          auto
          added a comment - Author: {u'login': u'agirbal', u'name': u'agirbal', u'email': u'antoine@10gen.com'} Message: JAVA-428 : Support new ReadPreference semantics, deprecate SlaveOK Branch: master https://github.com/mongodb/mongo-java-driver/commit/3e96c2f055df6b47d7259a4eb7b142e5435d3a01
          Hide
          auto
          added a comment -

          Author:

          {u'login': u'agirbal', u'name': u'agirbal', u'email': u'antoine@10gen.com'}

          Message: JAVA-428: read pref not set on cursor
          Branch: master
          https://github.com/mongodb/mongo-java-driver/commit/6441b5da66a5f755fc421420c771b6d2a7534e15

          Show
          auto
          added a comment - Author: {u'login': u'agirbal', u'name': u'agirbal', u'email': u'antoine@10gen.com'} Message: JAVA-428 : read pref not set on cursor Branch: master https://github.com/mongodb/mongo-java-driver/commit/6441b5da66a5f755fc421420c771b6d2a7534e15
          Hide
          auto
          added a comment -

          Author:

          {u'login': u'agirbal', u'name': u'agirbal', u'email': u'antoine@10gen.com'}

          Message: JAVA-428: be consistent for setter
          Branch: master
          https://github.com/mongodb/mongo-java-driver/commit/1101a2dc4d8e07b6f09cddd827ad992fef8a4547

          Show
          auto
          added a comment - Author: {u'login': u'agirbal', u'name': u'agirbal', u'email': u'antoine@10gen.com'} Message: JAVA-428 : be consistent for setter Branch: master https://github.com/mongodb/mongo-java-driver/commit/1101a2dc4d8e07b6f09cddd827ad992fef8a4547
          Hide
          Remon van Vliet
          added a comment -

          Just curious, but is there any particular reason you cannot pass a ReadPreference instance with finds rather than just allowing developers to set the value for the collection instance? The DBCollection.find(..) method signatures are becoming increasingly inconsistent.

          Show
          Remon van Vliet
          added a comment - Just curious, but is there any particular reason you cannot pass a ReadPreference instance with finds rather than just allowing developers to set the value for the collection instance? The DBCollection.find(..) method signatures are becoming increasingly inconsistent.
          Hide
          auto
          added a comment -

          Author:

          {u'login': u'scotthernandez', u'name': u'Scott Hernandez', u'email': u'scotthernandez@gmail.com'}

          Message: JAVA-428: enable tagging on ReadPrefs
          Branch: master
          https://github.com/mongodb/mongo-java-driver/commit/14ae90be2964156e032739e158303a3dc1940bfa

          Show
          auto
          added a comment - Author: {u'login': u'scotthernandez', u'name': u'Scott Hernandez', u'email': u'scotthernandez@gmail.com'} Message: JAVA-428 : enable tagging on ReadPrefs Branch: master https://github.com/mongodb/mongo-java-driver/commit/14ae90be2964156e032739e158303a3dc1940bfa

            People

            • Votes:
              1 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since reply:
                2 years, 21 weeks, 5 days ago
                Date of 1st Reply: