阻止,直到新的副本集配置到位

时间:2016-01-06 11:32:55

标签: python mongodb pymongo

我的Python Web应用程序有几个连接注册到同一个MongoDb服务器,但有3个不同的数据库。该申请由4名Gunicorn工作人员负责。

我正在使用副本集。

当主服务器关闭时,当前查询失败并在MongoReplicaSetClient中调度刷新(2.8,但我猜在3.2中它是相同的)。如果时间选择了新的主节点,并且MonitorThread获取有关更新客户端连接的信息,则下一个查询可能会成功。

但刷新仅影响此客户端。连接同一MongoDB服务器的其他客户端不会受到影响 - 每个客户端都会发生相同的故事。 这意味着如果每个工作者连接到同一MongoDB服务器上的3个数据库,并且我重复相同的HTTP请求,当主要服务器失败时使用所有3个数据库,则无限时间更新所有连接的客户端。如果每个HTTP请求循环到4个中的每个工作者,我们需要12个请求来更新每个Mongo客户端。但实际上这些要求并没有循环使用。

查看PyMongo代码 MongoReplicaSetClient._send_message_with_response我看到,当主要版本关闭时,会调用self.disconnect来调用self.__schedule_refresh。此方法具有参数sync,允许“阻止直到刷新完成”。

我的想法是捕获AutoReconnect异常并在连接到失败的主要和阻止的所有客户端上调用__schedule_refresh(sync=True),直到新的副本集配置到位。因此,在数据库正常之前,不会处理HTTP请求(导致500)。

但是__schedule_refresh是一种私有方法。此外,我不知道在所有客户端上按顺序调用它会是快速的 - 看起来MonitorThread会间隔工作。

或许我可以使用MongoReplicaSetClient.refresh

您如何看待这个想法?它有缺点吗?

你能帮我实施吗?

1 个答案:

答案 0 :(得分:0)

有趣的问题。

如果您在一个有大量请求进入的环境中运行,我建议反对在IO上有任何工作人员阻止,特别是像等待的网络调用为小学生提出来。

我建议尝试从您的mongo客户端捕获可能表明服务器已关闭并向调用者返回503s的异常。 503s通常是传达资源不可用的好方法,并建议稍后重试。

你的mongo数据库 会在使用过程中关闭并让appserver检测到这一点,转储请求并返回503s是一种处理流量的方法,否则会开始阻塞,线程耗尽并杀死应用服务器。让appserver摆脱所有这些会导致等待和可能失败的调用。

这是REST服务中常用的习惯用法:http://www.restpatterns.org/HTTP_Status_Codes/503_-_Service_Unavailable

您甚至可以添加“Retry-After”标头,以指示客户端将来何时尝试重试。有关Retry-After标题的更多信息以及某些浏览器如何解释它:

Retry-after HTTP response header - does it affect anything?

HTH