Paul Gregoire
Paul Gregoire

Reputation: 9793

How to prefer reads on secondaries in MongoDb

When using mongodb in a replica set configuration (1 arbiter, 1 primary, 2 slaves); how do I set a preference that read be performed against the secondaries and leave the primary only for writes? I'm using MongoDb 2.0.4 with Morphia. I see that there is a slaveOk() method, but I'm not sure how that works.

Morphia http://code.google.com/p/morphia/

Details My Mongo is set with the following options:

mongo.slaveOk();
mongo.setWriteConcern(WriteConcern.SAFE);

I am attempting to use the following (this may be answer -btw):

Datastore ds = getDatastore();
Query<MyEntity> query = ds.find(MyEntity.class).field("entityId").equal(entityId);
query.queryNonPrimary(); // appears equivalent to ReadPrefererence.secondary()
MyEntity entity = query.get();

Upvotes: 9

Views: 13712

Answers (4)

Jose Quinteiro
Jose Quinteiro

Reputation: 489

For the Java driver 3.6 the method is now

    MongoClientOptions l_opts =
            MongoClientOptions
            .builder()
            .readPreference( ReadPreference.secondary() )
            .build();

    ServerAddress l_addr = new ServerAddress( "localhost", 27017 );

    try
    (
            MongoClient l_conn = new MongoClient( l_addr, l_opts );
    )
    {
       ...

Upvotes: 0

Nic Cottrell
Nic Cottrell

Reputation: 9665

It seems that the current method (as per Java driver 2.8+) is to do

MongoOptions options = new MongoOptions();
options.setReadPreference(ReadPreference.secondaryPreferred());

then

mongo = new com.mongodb.Mongo(Arrays.asList(address1, address2), options);

This will make all connections prefer using secondaries, but will use the primary as a backup if the secondary is down or unavailable for some reason.

Upvotes: 2

Paul Gregoire
Paul Gregoire

Reputation: 9793

The correct answer, after much blood and sweat is as follows:

  • To prefer all reads / queries hit the secondaries, only slaveOk() need be set
  • To prefer only selected reads use secondaries, do not set slaveOk() and use queryNonPrimary() instead per query

It is also a good practice to set an appropriate write concern when using replica sets, like so:

mongo.setWriteConcern(WriteConcern.REPLICAS_SAFE);

Upvotes: 8

Gregor
Gregor

Reputation: 1458

Use the "SECONDARY" read preference http://www.mongodb.org/display/DOCS/Read+Preferences+and+Tagging+in+The+Java+Driver

"SECONDARY : Read from a secondary node if available, otherwise error."

Upvotes: 1

Related Questions