8

I've implemented a replica set that I'm using globally. I have my master in Oregon, US and 4 secondaries. California and Virginia, Frankfurt and Sydney. I also have web servers in those same regions as well. Those web servers connect to mongo using mongoose:

var mongoose = require("mongoose");
var dbUrl = "mongodb://***.***.***.***:27017,***.***.***.***:27017,***.***.***.***:27017,***.***.***.***:27017,***.***.***.***:27017/exampleDb";
var dbOptions : {
   "replSet": {
      "rs_name": "exampleRepSet",
      "readPreference": "ReadPreference.SECONDARY_PREFERRED",
      "read_preference": "ReadPreference.SECONDARY_PREFERRED",
      "w":0,
      "slaveOk": true
    }
}
mongoose.connect(dbUrl, dbOptions);

My problem is that my client's have higher latency to the database depending on how far away they are from the master. California get 40ms while Sydney gets 400ms. I don't understand why this is happening since they should be reading off of the secondary database in their region.

I understand that writes must be done to the primary but even if I perform a find then shouldn't it be done on the regional secondary and return pretty quick?

I realize there are some redundant options in that config but I'm getting desperate. I've also tried the option "ReadPreference.NEAREST" to no avail.

Josh Elias
  • 3,250
  • 7
  • 42
  • 73

3 Answers3

3

Edit

Try setting the read preference on the connection string itself with mongodb://connection/db/?readPreference=secondary and not in the dbOptions. I can't find anything in the node-mongodb-native that says a read preference can be added to the replset config. http://mongodb.github.io/node-mongodb-native/2.0/api/ReplSet.html

Old Answer

You may need to set the setting to nearest and not secondary preferred. http://docs.mongodb.org/manual/reference/read-preference/#nearest

ThrowsException
  • 2,586
  • 20
  • 37
  • I believe the SECONDARY_PREFERRED option will act the same as NEAREST with the exception that it will prefer to read off of a secondary. http://docs.mongodb.org/manual/core/read-preference-mechanics/#replica-set-read-preference-behavior-nearest – Josh Elias Jul 13 '15 at 06:25
  • hard coding that option in the mongodb connection url would indeed work but that's not the mongoose solution I was hoping for – Josh Elias Jul 23 '15 at 18:43
3

Try using the following options:

var mongoose = require("mongoose");
var dbUrl = "mongodb://***.***.***.***:27017,***.***.***.***:27017,***.***.***.***:27017,***.***.***.***:27017,***.***.***.***:27017/exampleDb";

mongoose.connect(dbUrl, {
    server: { 
        readPreference: "nearest", 
        strategy: "ping"
    },
    replset: { 
        rs_name: "exampleRepSet", 
        readPreference: "nearest", 
        strategy: "ping"
    }
});

Whilst the documentation specifies ping as the default strategy, it seems Mongoose mandates that you specify one when you use readPreference.

Also note that secondaryPreferred is not the same thing as nearest. secondaryPreferred prefers reads off of secondary members (as the name suggests) regardless of network latency, where nearest prioritizes reads to the member with the lowest amount of network latency.

Short of a misconfiguration in your replica set, make sure your primary is online and reachable - by default Mongoose will refuse to use a secondary if the primary is offline.

jduncanator
  • 2,154
  • 1
  • 22
  • 39
  • Is it just me or are the mongoose options a bit messy? – Josh Elias Jul 23 '15 at 18:43
  • 1
    @JoshElias Yes, certainly agree with you there. What makes it worst is a large portion of their documentation is horrible when it comes to describing options and providing examples. – jduncanator Jul 23 '15 at 23:30
  • Yes their documentation is horrible and they are very limited in the examples they provide. One reason I'm moving away from them. – Josh Elias Jul 23 '15 at 23:42
0
dbOptions.db = {
   readPreference: "secondaryPreferred",
};

This worked for me

Saif
  • 41
  • 4