我的工作环境:
mongo-1:"172.28.32.58:28010"
mongo-2:"172.28.32.59:28010"
mongo-3:"172.28.32.60:28010"
NOTE: filename: test_pymongo.py
from pymongo import MongoClient
from pymongo import ReadPreference
# single mongo
#c = MongoClient(host="mongo-1", port=28010) # okay
#c = MongoClient('mongodb://admin:123456@mongo-1:28010,mongo-2:28010/?replicaSet=rsname')
# mongo cluster
#c = MongoClient('mongodb://admin:123456@mongo-1:28010,mongo-2:28010,mongo-3:28010')
c = MongoClient('mongodb://admin:123456@mongo-1:28010,mongo-2:28010,mongo-3:28010',read_preference=ReadPreference.SECONDARY)
c = MongoClient('mongodb://admin:123456@mongo-1:28010,mongo-2:28010,mongo-3:28010',read_preference=ReadPreference. SECONDARY_PREFERRED)
#c = MongoClient('mongodb://admin:123456@mongo-1:28010,mongo-2:28010,mongo-3:28010',read_preference=ReadPreference.NEAREST)
#c = MongoClient('mongodb://admin:123456@mongo-1:28010,mongo-2:28010,mongo-3:28010/?readPreference=secondary')
#c = MongoClient('mongodb://admin:123456@mongo-3:28010/?readPreference=secondary')
print c.nodes
print c.database_names()
输出结果:
$ python test_pymongo.py
Traceback (most recent call last):
File "test_pymongo.py", line 16, in <module>
print c.database_names()
File "/root/.virtualenvs/py2.7.13mpc/lib/python2.7/site-packages/pymongo/mongo_client.py", line 1088, in database_names
"listDatabases")["databases"]]
File "/root/.virtualenvs/py2.7.13mpc/lib/python2.7/site-packages/pymongo/database.py", line 478, in command
with client._socket_for_reads(read_preference) as (sock_info, slave_ok):
File "/root/.pyenv/versions/2.7.13/lib/python2.7/contextlib.py", line 17, in __enter__
return self.gen.next()
File "/root/.virtualenvs/py2.7.13mpc/lib/python2.7/site-packages/pymongo/mongo_client.py", line 798, in _socket_for_reads
with self._get_socket(read_preference) as sock_info:
File "/root/.pyenv/versions/2.7.13/lib/python2.7/contextlib.py", line 17, in __enter__
return self.gen.next()
File "/root/.virtualenvs/py2.7.13mpc/lib/python2.7/site-packages/pymongo/mongo_client.py", line 762, in _get_socket
server = self._get_topology().select_server(selector)
File "/root/.virtualenvs/py2.7.13mpc/lib/python2.7/site-packages/pymongo/topology.py", line 210, in select_server
address))
File "/root/.virtualenvs/py2.7.13mpc/lib/python2.7/site-packages/pymongo/topology.py", line 186, in select_servers
self._error_message(selector))
pymongo.errors.ServerSelectionTimeoutError: No replica set members match selector "Primary()"
连接到mongo-2:
$ /opt/mongodb/bin/mongo 127.0.0.1:28010
MongoDB shell version: 3.2.12
connecting to: 127.0.0.1:28010/test
sys95:PRIMARY> use admin;
switched to db admin
sys95:PRIMARY> db.auth('admin','123456')
1
sys95:SECONDARY> rs.slaveOk();
sys95:SECONDARY> show dbs;
admin 0.000GB
cmdb 0.001GB
local 0.002GB
mpc 0.001GB
uop 0.000GB
sys95:SECONDARY> rs.conf();
{
"_id" : "sys95",
"version" : 1,
"protocolVersion" : NumberLong(1),
"members" : [
{
"_id" : 0,
"host" : "172.28.32.58:28010",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 3,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "172.28.32.59:28010",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 2,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "172.28.32.60:28010",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("597955a8d6042b84ccda4599")
}
}
sys95:SECONDARY>
sys95:SECONDARY> rs.status();
{
"set" : "sys95",
"date" : ISODate("2017-08-10T13:54:20.760Z"),
"myState" : 2,
"term" : NumberLong(13),
"heartbeatIntervalMillis" : NumberLong(2000),
"members" : [
{
"_id" : 0,
"name" : "172.28.32.58:28010",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2017-08-10T13:54:14.845Z"),
"lastHeartbeatRecv" : ISODate("2017-08-10T13:31:34.288Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "No route to host",
"configVersion" : -1
},
{
"_id" : 1,
"name" : "172.28.32.59:28010",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY", ## mongo-2 is work well!
"uptime" : 8331,
"optime" : {
"ts" : Timestamp(1502371925, 1),
"t" : NumberLong(13)
},
"optimeDate" : ISODate("2017-08-10T13:32:05Z"),
"infoMessage" : "could not find member to sync from",
"configVersion" : 1,
"self" : true
},
{
"_id" : 2,
"name" : "172.28.32.60:28010",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2017-08-10T13:54:16.797Z"),
"lastHeartbeatRecv" : ISODate("2017-08-10T13:32:10.636Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "No route to host",
"configVersion" : -1
}
],
"ok" : 1
}
sys95:SECONDARY>
sys95:SECONDARY> rs.isMaster()
{
"hosts" : [
"172.28.32.58:28010",
"172.28.32.59:28010",
"172.28.32.60:28010"
],
"setName" : "sys95",
"setVersion" : 1,
"ismaster" : false,
"secondary" : true,
"me" : "172.28.32.59:28010",
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2017-08-11T02:39:19.300Z"),
"maxWireVersion" : 4,
"minWireVersion" : 0,
"ok" : 1
}
结果:
和DBA确认过,如果Mongo集群中有3个节点,2个关掉之后,只保留一个secondary节点,没有primary节点,是无法对外提供功能的。
No primary available for writes
No replica set members match selector "Primary()"
扩展阅读:
High Availability and PyMongo¶
http://api.mongodb.com/python/current/examples/high_availability.html
简介:
Read preference:
Read preference is configured using one of the classes from read_preferences (Primary, PrimaryPreferred, Secondary, SecondaryPreferred, or Nearest). For convenience, we also provide ReadPreference with the following attributes:
PRIMARY: Read from the primary. This is the default read preference, and provides the strongest consistency. If no primary is available, raise AutoReconnect.
PRIMARY_PREFERRED: Read from the primary if available, otherwise read from a secondary.
SECONDARY: Read from a secondary. If no matching secondary is available, raise AutoReconnect.
SECONDARY_PREFERRED: Read from a secondary if available, otherwise from the primary.
NEAREST: Read from any available member.
https://stackoverflow.com/questions/38762897/pymongo-unable-to-connect-to-primary/45616549#45616549
简介:
stackoverfow 上一个类似的问题。