聚合国内IT技术精华文章,分享IT技术精华,帮助IT从业人士成长

解决 MongoDB 的 cursor id is not valid at server 问题

2013-07-15 10:01 浏览: 1780341 次 我要评论(0 条) 字号:

最近在用 Python 抓些网站的数据到 MongoDB 数据库。偶尔会遇到
pymongo.errors.OperationFailure: cursor id '26777532088498352' not valid at server
这样的问题。今天看了下文档,找到了原因。

你在用 db.collection.find() 的时候,它返回的不是所有的数据,而实际上是一个“cursor”。它的默认行为是:第一次向数据库查询 101 个文档,或 1 MB 的文档,取决于哪个条件先满足;之后每次 cursor 中的文档用尽后,查询 4 MB 的文档。另外,find()默认行为是返回一个 10 分钟无操作后超时的 cursor。如果我一个 batch 的文档十分钟内没处理完,过后再处理完了,再用同一个 cursor id 向服务器取下一个 batch,这时候 cursor id 当然已经过期了,这也就能解释为啥我得到 cursor id 无效的错误了。

Stack Overflow 上有人提出过解决方法,是在 find() 时传入 timeout=False 来禁用 10 分钟超时的保护措施。但是我觉得这是非常差的办法,因为如果你循环时产生异常,甚至断电或断网,都会导致 MongoDB 服务器资源永远无法被释放。而更好的办法是(我也发在了 Stack Overflow 上),估计一个 batch 大小,让 MongoDB 客户端每次抓取的文档在 10 分钟内能用完,这样客户端就不得不 10 分钟内至少联系服务器一次,保证 cursor 不超时。

具体用法:

for document in db.collection.find().batch_size(30):
    do_time_consuming_things()


网友评论已有0条评论, 我也要评论

发表评论

*

* (保密)

Ctrl+Enter 快捷回复