PyMongo 在大量查询后引发 [errno 49] can't assign requested address
PyMongo raises [errno 49] can't assign requested address after a large number of queries
我有一个 MongoDB 集合,其中包含超过 1,000,000 个文档。
我正在执行初始 .find({ my_query })
到 return 这些文档的子集(~25,000 个文档),然后我将其放入 list
对象中。
然后我遍历每个对象,解析列表中 returned 文档中的一些值,并通过代码使用这些解析值执行额外的查询:
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.name
和 opponents.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
有关但与 pymongo 无关的其他 SO 问题,并且答案不会引导我到任何地方。
更新:
根据下面 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 上是 运行。
这是因为您没有正确使用 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 集合,其中包含超过 1,000,000 个文档。
我正在执行初始 .find({ my_query })
到 return 这些文档的子集(~25,000 个文档),然后我将其放入 list
对象中。
然后我遍历每个对象,解析列表中 returned 文档中的一些值,并通过代码使用这些解析值执行额外的查询:
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.name
和 opponents.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
有关但与 pymongo 无关的其他 SO 问题,并且答案不会引导我到任何地方。
更新:
根据下面 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 上是 运行。
这是因为您没有正确使用 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)