7

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();
Paul Gregoire
  • 9,350
  • 11
  • 56
  • 128
  • vote it down without a comment, how helpful :( – Paul Gregoire Jan 29 '13 at 17:27
  • The question does not show any research effort. – Sergio Tulentsev Jan 29 '13 at 17:31
  • added it.. slaveOk.. will it work? no idea yet but it doesn't look right to me. – Paul Gregoire Jan 29 '13 at 17:35
  • "no idea yet" - that's what I mean. Have you tried googling before asking the question? – Sergio Tulentsev Jan 29 '13 at 17:37
  • i'm looking into query.queryNonPrimary() atm – Paul Gregoire Jan 29 '13 at 17:37
  • yes, googled first; prefer answers from SO since they come with the experience of many developers. – Paul Gregoire Jan 29 '13 at 17:38
  • anyhow just lashing out due to the trolling that goes on here; ask a question that you need an answer to and it gets less visibility due to people automatically down-voting it; this gets really annoying. Especially when there's no comment to explain or assist. – Paul Gregoire Jan 29 '13 at 17:41
  • Wow dude, i'm starting to think less of you. if SO is not for assistance maybe they should update the about page: "With your help, we're working together to build a library of detailed answers to every question about programming." I for one certainly think this question would be very helpful for people in my situation; apparently you don't have a good answer but would rather knock others instead; how does that help anyone?? – Paul Gregoire Jan 29 '13 at 17:49
  • Man, please. [stackoverflow search](http://stackoverflow.com/search?q=mongodb+java+read+secondary), [google search](https://www.google.co.th/search?q=mongodb+java+read+secondary&aq=f&oq=mongodb+java+&aqs=chrome.0.59j57j0l2j61j60.2695&sourceid=chrome&ie=UTF-8). First links in both searches contain answer to your question. Research effort, that's what I'm talking about. – Sergio Tulentsev Jan 29 '13 at 17:53
  • Also [duckduckgo search](https://duckduckgo.com/?q=mongodb+java+read+secondary) – Sergio Tulentsev Jan 29 '13 at 17:59
  • Actually http://stackoverflow.com/questions/6520439/how-to-configure-mongodb-java-driver-mongooptions-for-production-use/6521704#6521704 has the closest answer and is most helpful; but it says nothing about Morphia which is the ORM library noted in the question; hence none of those links have the answer. Thanks for helping though. – Paul Gregoire Jan 29 '13 at 18:02
  • AFAIK, morphia is irrelevant here, since it relies on java driver for request routing. I might be wrong, though. – Sergio Tulentsev Jan 29 '13 at 18:03
  • 1
    Added "morphia" tag. It's documentation looks pretty thin on how it wraps the Java driver, you might need to look at the source. The relevant Java driver doc is http://api.mongodb.org/java/current/com/mongodb/ReadPreference.html and the general MongoDB docs are at: http://docs.mongodb.org/manual/applications/replication/#read-preference-modes – mjhm Jan 29 '13 at 18:23
  • Yes, doc details are scarce for sure; but it is a really good library. – Paul Gregoire Jan 29 '13 at 18:28

4 Answers4

6

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);
Paul Gregoire
  • 9,350
  • 11
  • 56
  • 128
2

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.

Nic Cottrell
  • 8,051
  • 4
  • 46
  • 70
  • Good to know, I'm sure I'll run into this again if Mongo stays relevant – Paul Gregoire Jun 27 '13 at 14:29
  • You can also set the read preference after creation of the mongo client like this `mongoClient.setReadPreference(ReadPreference.secondaryPreferred())`. `mongoClient.slaveOk()` is deprecated. – jschreiner Mar 26 '14 at 14:48
1

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

geakie
  • 1,408
  • 9
  • 9
0

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 );
    )
    {
       ...
Jose Quinteiro
  • 379
  • 3
  • 7