【问题标题】:PyMongo raises [errno 49] can't assign requested address after a large number of queriesPyMongo 在大量查询后引发 [errno 49] 无法分配请求的地址
【发布时间】:2015-05-26 20:49:53
【问题描述】:

我有一个 MongoDB 集合,其中包含 > 1,000,000 个文档。 我正在执行初始 .find({ my_query }) 以返回这些文档的子集(约 25,000 个文档),然后将其放入 list 对象中。

然后我循环遍历每个对象,从列表中返回的文档中解析一些值,并通过代码使用这些解析值执行附加查询:

def _perform_queries(query):
    conn = pymongo.MongoClient('mongodb://localhost:27017')
    try:
        coll = conn.databases['race_results']
        races = coll.find(query).sort("date", -1)
    except BaseException, err:
        print('An error occured in runner query: %s\n' % err)
    finally:
        conn.close()
        return races

在这种情况下,我的query 字典是:

{"$and": [{"opponents":
    {"$elemMatch": {"$and": [
        {"runner.name": name},
        {"runner.jockey": jockey}
    ]}}},
    {"summary.dist": "1"}
]}

这是我的问题。我在opponents.runner.nameopponents.runner.jockey 上创建了一个索引。这使得查询非常非常快。但是,在连续进行了大约 10,000 次查询后,pymongo 引发了异常:

pymongo.errors.AutoReconnect: [Errno 49] Can't assign requested address

当我删除索引时,我没有看到这个错误。但是每次查询大约需要0.5 seconds,这在我的情况下是不可用的。

有人知道为什么会出现[Errno 49] can't assign requested address 吗?我看到了一些其他与can't assign requested address 相关的 SO 问题,但与 pymongo 无关,而且这些答案不会带我去任何地方。

更新:

按照下面 Serge 的建议,这里是 ulimit -a 的输出:

core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 2560
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 709
virtual memory          (kbytes, -v) unlimited

我的 MongoDB 在 OS X Yosemite 上运行。

【问题讨论】:

    标签: python mongodb pymongo


    【解决方案1】:

    这是因为您错误地使用了 PyMongo。您正在为每个查询创建一个新的 MongoClient,这需要您为每个新查询打开一个新套接字。这破坏了 PyMongo 的连接池,除了速度极慢之外,这还意味着您打开和关闭套接字的速度比 TCP 堆栈能够跟上的速度快:您将太多的套接字留在 TIME_WAIT 状态,因此最终会耗尽端口。

    幸运的是,修复很简单。创建一个 MongoClient 并在整个过程中使用它:

    conn = pymongo.MongoClient('mongodb://localhost:27017')
    coll = conn.databases['race_results']
    
    def _perform_queries(query):
        return coll.find(query).sort("date", -1)
    

    【讨论】:

    • 啊,是的!这现在更有意义了。我每天都在学习越来越多的关于 MongoDB 的知识。谢谢!已接受答案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2023-03-11
    • 2017-09-13
    • 2012-11-30
    • 2018-04-27
    • 2021-05-26
    • 2020-09-04
    相关资源
    最近更新 更多