简体   繁体   English

Pymongo读取首选项-ServerSelectionTimeoutError:无主要可用于写入

[英]Pymongo Read Preferences - ServerSelectionTimeoutError: No primary available for writes

When connection to a MongoDB replica set, I'm able to read from the secondaries, but afterwards, when writing using the same connection, I receive the following error: 当连接到MongoDB副本集时,我可以从第二副本中读取内容,但是随后,当使用相同的连接进行写入时,会收到以下错误:

pymongo.errors.ServerSelectionTimeoutError: No primary available for writes

Python 3.4.3 Pymongo 3.2.2 Python 3.4.3 Pymongo 3.2.2

My connection: 我的联系:

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')

IMPORTANT: When removing both 'replicaSet' and 'readPrefence' fields, the connection works. 重要说明:同时删除“ replicaSet”和“ readPrefence”字段时,连接有效。

In the server: 在服务器中:

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() db.isMaster()

mongodb0 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 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 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
}

I hypothesize that: 我假设:

  1. Your driver can connect to your secondary's public IP at either 10.150.151.141:27017 or 10.150.151.155:27017 or both. 您的驱动程序可以通过10.150.151.141:27017或10.150.151.155:27017或两者连接到辅助站点的公共IP。
  2. Your connection string points to one of the above public IPs for secondaries, or your connection string points to the public IP of the primary. 您的连接字符串指向上面的辅助IP的公共IP之一,或者您的连接字符串指向主要的IP的公共IP。
  3. The replica set uses internal IPs in its configuration which are not accessible to your client machine: it cannot connect to "mongodb0", "mongodb1", or "mongodb2". 副本集在其配置中使用客户端计算机无法访问的内部IP:它无法连接到“ mongodb0”,“ mongodb1”或“ mongodb2”。

You need to reconfigure your replica set using public IPs. 您需要使用公共IP重新配置副本集。 If you're curious why this is so, it's explained in the Server Discovery and Monitoring Spec . 如果您好奇为什么会这样,请在服务器发现和监视规范中进行说明 But the gist is this: whatever is listed for members' hostnames in rs.conf() must be public hostnames accessible to your client machine. 但是要点是: rs.conf()列出的成员主机名必须是客户端计算机可访问的公用主机名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM