从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一起工作的事实表明使用的主机格式字符串是有效的。那么为什么第一个在重启服务时失败呢?
答案 0 :(得分:1)
可以在解析器的pymongo连接split_hosts过程中找到答案here。
解析器不会忽略间距,即使URI规范(RFC2396)指定应排除空格并且空格可用作分隔符(第2.3.4节)。在主机名中包含空格会导致网络连接 错误。
host2字符串工作的原因是列表中的第一个主机仍然有效,因为它不以空格开头并正确解析。另外两个是错误的,但是pymongo驱动程序只需要一个就可以找到一个正常运行的主机 然后它可以使用查找所有其他的。
因此,问题的答案是删除逗号后面的空格。
hosts1 = "host1,host2,host3,host4"
修复很简单,但是,这种情况的最大问题是在服务重新启动之前问题不会显现, 在副本集的成员资格发生变化后很长一段时间。