2015-11-04 62 views
0

從mongoDB副本集中刪除主機但未更改主機使用該副本集傳遞給mongo_client(或MongoReplicaSetClient)的主機字符串在重新啓動服務時似乎破壞了pymongo連接。此異常升高是:pymongo在副本集組合更改時無法連接

pymongo.errors.ServerSelectionTimeoutError:主機4:27017:[錯誤-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') 

因此,該腳本將失敗,並與host1,但與host2和host3,即。

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

或:

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

的問題與此是,直到重新啓動該服務這個問題不會變得明顯,副本集成員更改後可能很多後來發生。

它與hosts2一起使用的事實表明所使用的主機格式字符串是有效的。那麼爲什麼當重新啓動服務時第一個失敗呢?

回答

1

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

即使URI規範(RFC2396)指定應該排除空格並且可以將空格用作分隔符(第2.3.4節),分析器也不會忽略間距。在主機名中包含空格導致聯網 錯誤。

host2字符串工作的原因是列表中的第一個主機仍然有效,因爲它不以空格開頭並正確解析。另外兩個是錯誤的,但是pymongo驅動程序只需要一個找到一個正常運行的主機,然後它可以使用查找所有其他的主機。

因此,問題的答案是刪除逗號後的空格。

hosts1 = "host1,host2,host3,host4" 

解決方法是簡單的,但是,這種情況最大的問題是,直到服務重新啓動的問題不會變得明顯,副本集的成員資格已經更改後可能 是很長一段時間。