如何处理 PyMongo/MongoEngine AutoReconnect?

How to handle PyMongo/MongoEngine AutoReconnect?

当我使用 MongoEngine 在一个集合中迭代查询超过 100K 个文档时。它通常以 "pymongo.errors.AutoReconnect: [Errno 54] Connection reset by peer".

结尾

我已经检查了其他 answer/solution 的 AutoReconnect,但我怀疑这些是否与我遇到的情况相同。所以我post这个问题。

是否有避免自动重新连接的提示或我可以做的任何诊断?

以下是我收集的一些解决方案:

  1. 使用 try...catch...
  2. 使用 c 扩展 (pymongo_has_c())
  3. 使用像 MongoDBProxy 这样的第三方库
  4. 设置关键字参数,如超时和bulk_size(我试过了,但没有用)

Mongo代理对我来说开箱即用 Mongo 引擎。到处使用 try .. except 很烦人。最后我得到了如此快速的解决方案。希望对你有帮助。

import logging

from mongoengine import *

class SafeDocumentMixin:

    def save_safe(self, *args, **kwargs):
        for attempt in range(5):
            try:
                return self.save(*args, **kwargs)
            except pymongo.errors.AutoReconnect as e:
                wait_t = 0.5 * pow(2, attempt) # exponential back off
                l.warning("PyMongo auto-reconnecting... %s. Waiting %.1f seconds.", str(e), wait_t)
                time.sleep(wait_t)

    @classmethod
    def objects_safe(cls, *args, **kwargs):
        for attempt in range(5):
            try:
                return cls.objects(*args, **kwargs)
            except pymongo.errors.AutoReconnect as e:
                wait_t = 0.5 * pow(2, attempt) # exponential back off
                logging.warning("PyMongo auto-reconnecting... %s. Waiting %.1f seconds.", str(e), wait_t)
                time.sleep(wait_t)

class Person(Document, SafeDocumentMixin):
    name = StringField()
    age = IntField()

然后像这样使用

Person.objects_safe(age='23')

可能更多的解决方案是 monkey patching 但我更愿意看到我正在调用自定义方法