Pymongo Read Preferences - ServerSelectionTimeoutError: No primary available for writes

Pymongo Read Preferences - ServerSelectionTimeoutError: No primary available for writes

当连接到 MongoDB 副本集时,我能够从辅助副本读取,但之后,当使用相同的连接写入时,我收到以下错误:

pymongo.errors.ServerSelectionTimeoutError: No primary available for writes

Python 3.4.3 皮蒙戈 3.2.2

我的连接:

var_host = 'XXX.XXX.XXX.XXX' # Public IP
var_port = 27017
var_username = 'username'
var_password = 'password'
mongo_uri = 'mongodb://%s:%s@%s:%s' % (username, password, host, port)
client_db = MongoClient(mongo_uri,
                 replicaSet='rs0',
                 readPreference='secondaryPreferred')

重要提示: 删除 'replicaSet' 和 'readPrefence' 字段时,连接有效。

在服务器中:

rs0:PRIMARY> rs.status()
{"set" : "rs0",
 "date" : ISODate("2016-11-23T13:09:55.699Z"),
 "myState" : 1,
 "term" : NumberLong(4),
 "heartbeatIntervalMillis" : NumberLong(2000),
 "members" : [
    {
        "_id" : 0,
        "name" : "mongodb0:27017",
        "health" : 1,
        "state" : 1,
        "stateStr" : "PRIMARY",
        "uptime" : 64491,
        "optime" : {
            "ts" : Timestamp(1479906595, 21),
            "t" : NumberLong(4)
        },
        "optimeDate" : ISODate("2016-11-23T13:09:55Z"),
        "electionTime" : Timestamp(1479844637, 1),
        "electionDate" : ISODate("2016-11-22T19:57:17Z"),
        "configVersion" : 424888,
        "self" : true
    },
    {
        "_id" : 1,
        "name" : "mongodb2:27017",
        "health" : 1,
        "state" : 2,
        "stateStr" : "SECONDARY",
        "uptime" : 61631,
        "optime" : {
            "ts" : Timestamp(1479906593, 31),
            "t" : NumberLong(4)
        },
        "optimeDate" : ISODate("2016-11-23T13:09:53Z"),
        "lastHeartbeat" : ISODate("2016-11-23T13:09:53.776Z"),
        "lastHeartbeatRecv" : ISODate("2016-11-23T13:09:53.758Z"),
        "pingMs" : NumberLong(0),
        "syncingTo" : "XXXXXXXX:27017",
        "configVersion" : 424888
    },
    {
        "_id" : 2,
        "name" : "mongodb3:27017",
        "health" : 1,
        "state" : 2,
        "stateStr" : "SECONDARY",
        "uptime" : 61264,
        "optime" : {
            "ts" : Timestamp(1479906593, 31),
            "t" : NumberLong(4)
        },
        "optimeDate" : ISODate("2016-11-23T13:09:53Z"),
        "lastHeartbeat" : ISODate("2016-11-23T13:09:53.776Z"),
        "lastHeartbeatRecv" : ISODate("2016-11-23T13:09:55.493Z"),
        "pingMs" : NumberLong(0),
        "syncingTo" : "XXX:27017",
        "configVersion" : 424888
    }
   ],
   "ok" : 1}

db.isMaster()

mongodb0

rs0:PRIMARY> db.isMaster()
{
"hosts" : [
    "mongodb0:27017"
],
"passives" : [
    "10.150.151.141:27017",
    "10.150.151.155:27017"
],
"setName" : "rs0",
"setVersion" : 424888,
"ismaster" : true,
"secondary" : false,
"primary" : "mongodb0:27017",
"me" : "mongodb0:27017",
"electionId" : ObjectId("7fffffff0000000000000004"),
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2016-11-23T15:12:37.988Z"),
"maxWireVersion" : 4,
"minWireVersion" : 0,
"ok" : 1
}

mongodb1

rs0:SECONDARY> db.isMaster()
{
"hosts" : [
    "mongodb0:27017"
],
"passives" : [
    "10.150.151.141:27017",
    "10.150.151.155:27017"
],
"setName" : "rs0",
"setVersion" : 424888,
"ismaster" : false,
"secondary" : true,
"primary" : "mongodb0:27017",
"passive" : true,
"me" : "10.150.151.141:27017",
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2016-11-23T15:24:32.134Z"),
"maxWireVersion" : 4,
"minWireVersion" : 0,
"ok" : 1

mongodb2

 rs0:SECONDARY> db.isMaster()
 {
 "hosts" : [
    "mongodb0:27017"
 ],
 "passives" : [
    "10.150.151.141:27017",
    "10.150.151.155:27017"
 ],
"setName" : "rs0",
 "setVersion" : 424888,
"ismaster" : false,
"secondary" : true,
"primary" : "mongodb0:27017",
"passive" : true,
"me" : "10.150.151.155:27017",
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2016-11-23T15:21:54.971Z"),
"maxWireVersion" : 4,
"minWireVersion" : 0,
"ok" : 1
}

我假设:

  1. 您的驱动程序可以通过 10.150.151.141:27017 或 10.150.151.155:27017 或两者连接到辅助 public IP。
  2. 您的连接字符串指向上述 public 个辅助 IP 之一,或者您的连接字符串指向主 public IP。
  3. 副本集在其配置中使用内部 IP,您的客户端机器无法访问:它无法连接到"mongodb0"、"mongodb1" 或 "mongodb2".

您需要使用 public 个 IP 重新配置副本集。如果您好奇为什么会这样,Server Discovery and Monitoring Spec 中对此进行了解释。但要点是:在 rs.conf() 中为成员主机名列出的任何内容都必须是 public 您的客户端计算机可以访问的主机名。