Reputation: 61
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?
Upvotes: 6
Views: 8125
Reputation: 925
For me, few mongo server were crashed and hence I was seeing error. Please check your mongo db server connectivity
Upvotes: 0
Reputation: 1812
I know the post is already outdated, but I bumped into this issue last week and I was able to resolved the problem.
Few things you have to check:
&
should be &
otherwise you would get an 'entity issue'.27017
Use primaryPreffered
over secondaryPreferred
- this is if you want an application to read from the primary under normal circumstances, but to allow stale reads from secondaries when the primary is unavailable. This provides a “read-only mode” for your application during a failover. Using secondaryPreferred
is a counter-indications. Know more from mongodb official documentation here.
The obvious one is to check if the replica set is connected to each other, meaning there's an arbiter member, hence you would encounter that issue. I would like to bet if you only put the mongo1 and remove other replica set parameters, it would work perfectly.
replicaSet
not replicaset
as stated by lese. Upvotes: 0
Reputation: 4183
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.
Upvotes: 5
Reputation: 549
What am I doing wrong?
I think you shouldn't declare the arbiter in the connection string. Arbiter is not really a node it don't hold any data, its task is to partecipate in the vote of the primary node(the one who takes the writes) of the replicaSet.
You did well to add the arbiter, because without it nodes(and votes) was even, and you would anyway be facing with some cases of connection failure. Anyway your problem is not related to this. Do you really need that connect=replicaset
?
I don't know much about C# , but i read that connection strings have the same format for all the official drivers, also this is an example in php :
$m = new MongoClient("mongodb://mongo1:27017,mongo2:27018/?replicaSet=myrs&readPreference=secondary");
Are you testing eventual consistency? let me know what you think about it, i didnt had time to check it
don't know if its case-sensitive but watch out at the capital letter replicaSet=myrs
Upvotes: 0