Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to connect to a member of the replica set matching the read preference Primary

I have 3 mongodb nodes: primary, secondary and arbiter (version 2.4.9)

I have mongodb C# driver 1.8.3 I am using the following connection string:

connection string "mongodb://mongo2,mongo1,mongo3/?connect=replicaset&replicaset=myrs&readPreference=SecondaryPreferred"

When recording half case the driver throws an exception:

Unable to connect to a member of the replica set matching the read preference Primary

My code:

        var client = new MongoClient(connectionString);
        var server = client.GetServer();
        var database = server.GetDatabase(dbName);
        var collection = database.GetCollection<T>(collectionName);
        collection.Insert(newDoc);

What am I doing wrong?

like image 863
martyGale Avatar asked Jan 25 '14 12:01

martyGale


People also ask

Which read Preference mode allows a secondary to be the only choice for handling read operations on a Mongodb replica set?

Starting in version 4.4, primaryPreferred supports hedged reads on sharded clusters. Operations read only from the secondary members of the set. If no secondaries are available, then this read operation produces an error or exception.


1 Answers

I suspect it's because you provided wrong host names.

Here's one thing you should know, the available mongo instance list doesn't come from your connection string, it comes from the returned result of first available mongo instance. For example, when the driver communicates with instance mongo1, it gets a list of available instances, which you can get with the following command:

rs.status()

in my laptop it returns something like this:

{
    "set" : "rs0",
    "date" : ISODate("2014-01-27T06:43:11Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 0,
            "name" : "YX-ARCH:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 15894,
            "optime" : Timestamp(1390804960, 1),
            "optimeDate" : ISODate("2014-01-27T06:42:40Z"),
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "YX-ARCH:27011",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 31,
            "optime" : Timestamp(1390804960, 1),
            "optimeDate" : ISODate("2014-01-27T06:42:40Z"),
            "lastHeartbeat" : ISODate("2014-01-27T06:43:10Z"),
            "lastHeartbeatRecv" : ISODate("2014-01-27T06:43:10Z"),
            "pingMs" : 0,
            "syncingTo" : "YX-ARCH:27017"
        }
    ],
    "ok" : 1
}

Which means there are 2 instances YX-ARCH:27017 (Primary) & YX-ARCH:27011 (Secondary).

Now the point is, these host names must be resolvable in your IIS server, because your driver will uses these addresses to connect to mongo instances.

Thus if the host name resolves to a internet IP, while your mongo service is only available for intranet, you'll never be able to connect to it. And you get the error above.

One more thing, it's not recommended to create a new instance of MongoClient each time. From the document you can know it's thread-safe class. And the MongoClient is added to the driver to manage replica set stuff. So in my opinion you should keep it a single instance object. Because each time you create a new instance, it tries to get replica set settings from one instance, which is not really a good thing for the efficiency.

like image 79
yaoxing Avatar answered Oct 05 '22 10:10

yaoxing