当副本集组成发生变化时,pymongo无法连接

时间:2015-11-04 13:36:24

标签: python mongodb pymongo

从mongoDB副本集中删除主机,但不更改使用该副本集传递给mongo_client(或MongoReplicaSetClient)的主机字符串,似乎在重新启动服务时会破坏pymongo连接。提出的这个例外是:

pymongo.errors.ServerSelectionTimeoutError:host4:27017:[Errno -2]名称或服务未知......

问题可以解决如下:

hosts1 = "host1, host2, host3, host4"  # where host1 and host2 are not available anymore
hosts2 = "host3, host4"  # only has valid hosts
hosts3 = ["host1", "host2", "host3", "host4"]  # expressed as a list

client = MongoClient(hosts1, 27017, replicaset="rs0")
db = client['admin']
db.authenticate('user', 'pass')

因此脚本将与hosts1一起失败,但与host2和host3一起使用,即

client = MongoClient(hosts2, 27017, replicaset="rs0")  # works

或:

client = MongoClient(hosts3, 27017, replicaset="rs0")  # works

问题在于,在重新启动服务之前,这个问题并不明显,这可能会在副本集成员资格发生更改后很多时间发生。

它与hosts2一起工作的事实表明使用的主机格式字符串是有效的。那么为什么第一个在重启服务时失败呢?

1 个答案:

答案 0 :(得分:1)

可以在解析器的pymongo连接split_hosts过程中找到答案here

解析器不会忽略间距,即使URI规范(RFC2396)指定应排除空格并且空格可用作分隔符(第2.3.4节)。在主机名中包含空格会导致网络连接 错误。

host2字符串工作的原因是列表中的第一个主机仍然有效,因为它不以空格开头并正确解析。另外两个是错误的,但是pymongo驱动程序只需要一个就可以找到一个正常运行的主机 然后它可以使用查找所有其他的。

因此,问题的答案是删除逗号后面的空格。

hosts1 = "host1,host2,host3,host4"

修复很简单,但是,这种情况的最大问题是在服务重新启动之前问题不会显现, 在副本集的成员资格发生变化后很长一段时间。