Mongoose not reading from Mongo secondary database

2019-04-06 10:32发布

问题:

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.

回答1:

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.



回答2:

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



回答3:

dbOptions.db = {
   readPreference: "secondaryPreferred",
};

This worked for me