PyMongo引发[errno 49]在大量查询后无法分配请求的地址

时间:2015-03-23 18:13:23

标签: python mongodb pymongo

我有 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上运行。

1 个答案:

答案 0 :(得分:13)

这是因为你错误地使用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)