how to setup a replica set and later connect it using pymongo

284 views
Skip to first unread message

Jack J

unread,
Dec 22, 2015, 12:52:47 AM12/22/15
to mongodb-user

i am trying to connect mongodb using pymongo 3.2. firstly, i followed the instruction here to setup a replica set. Then i went to my primary server and try "rs.status()", which returned:

{
        "set" : "seekCluster",
        "date" : ISODate("2015-12-22T04:44:12.411Z"),
        "myState" : 1,
        "term" : NumberLong(9),
        "heartbeatIntervalMillis" : NumberLong(2000),
        "members" : [
                {
                        "_id" : 0,
                        "name" : "seek1:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 4677,
                        "optime" : {
                                "ts" : Timestamp(1450754784, 2),
                                "t" : NumberLong(9)
                        },
                        "optimeDate" : ISODate("2015-12-22T03:26:24Z"),
                        "lastHeartbeat" : ISODate("2015-12-22T04:44:12.044Z"),
                        "lastHeartbeatRecv" : ISODate("2015-12-22T04:44:12.389Z"),
                        "pingMs" : NumberLong(0),
                        "syncingTo" : "seek3:27017",
                        "configVersion" : 1
                },
                {
                        "_id" : 1,
                        "name" : "seek2:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 4677,
                        "optime" : {
                                "ts" : Timestamp(1450754784, 2),
                                "t" : NumberLong(9)
                        },
                        "optimeDate" : ISODate("2015-12-22T03:26:24Z"),
                        "lastHeartbeat" : ISODate("2015-12-22T04:44:12.170Z"),
                        "lastHeartbeatRecv" : ISODate("2015-12-22T04:44:10.833Z"),
                        "pingMs" : NumberLong(0),
                        "syncingTo" : "seek3:27017",
                        "configVersion" : 1
                },
                {
                        "_id" : 2,
                        "name" : "seek3:27017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 4679,
                        "optime" : {
                                "ts" : Timestamp(1450754784, 2),
                                "t" : NumberLong(9)
                        },
                        "optimeDate" : ISODate("2015-12-22T03:26:24Z"),
                        "electionTime" : Timestamp(1450754784, 1),
                        "electionDate" : ISODate("2015-12-22T03:26:24Z"),
                        "configVersion" : 1,
                        "self" : true
                }
        ],
        "ok" : 1
}

Later in pymongo, i did:

from pymongo import ReadPreference
        db = MongoClient("seek3", replicaSet='seekCluster',
                         readPreference='secondary',
                         localThresholdMS = 35)['seek']
        print db.read_preference  # it yields "Secondary(tag_sets=None)"
        print db["db"].find().count(), db.client

however, by printing "db.client" that gave me a: ('seek3', 27017), which is my primary server.

my questions are: 1. is that correct or wrong? 2. how can i know whether the query returns the data from a secondary server?

Jack J

unread,
Dec 22, 2015, 8:53:53 PM12/22/15
to mongodb-user
any comments? please:)

Bernie Hackett

unread,
Dec 29, 2015, 12:54:18 PM12/29/15
to mongodb-user
db.client is the instance of MongoClient for 'db'. It should print something like this:

>>> db.client
MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=False)

"host" is just the list of hosts you provided as the seed list to create the client (or the default host in my example). It is not necessarily the host used for queries.

> how can i know whether the query returns the data from a secondary server?

The best way to monitor this is to use the monitoring support added in PyMongo 3.1. See https://api.mongodb.org/python/current/api/pymongo/monitoring.html

Jack J

unread,
Jan 3, 2016, 7:15:19 PM1/3/16
to mongodb-user
excellent!
thank you very much!
...

Nathan Cope

unread,
Mar 30, 2016, 8:30:11 PM3/30/16
to mongodb-user
I have the same problem. We have one process that writes to primary and many processes that I want to read from secondaries. (Replication delays arent a problem)
I'm using the latest pymongo version 3.2.2

I used the monitoring method suggested and it reports its connecting to the primary. I cant get processes to connect to secondaries it always goes to primary. Even when I use Nearest it connects to primary when its clearly not the nearest.

con = MongoClient(hosts, event_listeners=[CommandLogger()], replicaSet='test', readPreference="secondary")

Any ideas how to resolve this?
...

Bernie Hackett

unread,
Mar 31, 2016, 11:11:13 AM3/31/16
to mongodb-user
> I used the monitoring method suggested and it reports its connecting to the primary.

PyMongo always connects to the primary (and all of the non-hidden secondaries) when you pass the replicaSet option. It will also always send write operations to the primary (only the primary can take writes). Only queries and query-like commands will be routed to a secondary
...

Nathan Cope

unread,
Mar 31, 2016, 2:16:19 PM3/31/16
to mongodb-user
So when issue an isMaster I always get the Primary. How can I be sure that query-like commands are routed to a secondary?

Bernie Hackett

unread,
Mar 31, 2016, 3:12:52 PM3/31/16
to mongodb-user
See the note about read_preference and codec_options here:


Commands sent through Database.command are, by default, sent to the primary.
...

Nathan Cope

unread,
Apr 1, 2016, 10:18:24 AM4/1/16
to mongodb-user

So how can I be sure that query-like commands are routed to a secondary? There must be a way for me to verify that a secondary is being used?

Thanks for the below note on the api but I don't understand the second sentence. So, 'command' doesn't obey read_pref but I must use read_pref params instead??

Note

command() does not obey read_preference or codec_options. You must use the read_preference and codec_options parameters instead.


...

Bernie Hackett

unread,
Apr 7, 2016, 6:23:35 PM4/7/16
to mongodb-user
That means instead of doing, for example:

database.command('ismaster')

You need to do:

from pymongo import ReadPreference
database.command('ismaster', read_preference=ReadPreference.SECONDARY)

This only applies to the command method. Most helpers for other query like operations obey the client, database, or collection level read preference you set. The reasoning for command() working this way is that most commands called through it only make sense to run on the primary, rather than an arbitrary replica set member. The ismaster command tells you a number of things about the current membership of the cluster and the replica set primary should be considered the canonical source of that information.
...
Reply all
Reply to author
Forward
0 new messages