Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose not reading from Mongo secondary database

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.

like image 430
Josh Elias Avatar asked Jul 12 '15 16:07

Josh Elias


1 Answers

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.

like image 200
jduncanator Avatar answered Nov 15 '22 04:11

jduncanator