Skip to content

Instantly share code, notes, and snippets.

@DennisXie
Last active December 6, 2018 08:58
Show Gist options
  • Save DennisXie/5721fc95484ff54b96b8a5e456a69399 to your computer and use it in GitHub Desktop.
Save DennisXie/5721fc95484ff54b96b8a5e456a69399 to your computer and use it in GitHub Desktop.
mongodb cursorNotFound exception
一段很简单的代码:
res = db.table.find({"uid": 12345})
l = [d['info'] for d in res]
在有100多条文档的时候,这段代码有时候会抛出 cursorNotFoundException
由于文档只有100多条,可以直接排除cursor超时的问题
经和SA进行确认,链接mongodb的时候使用的是url的方式,部署方式如下:
app->lbc->mongos->mongod
其中app->lbc使用了长连接的方式,但是lbc->mongos并没有使用长连接。
其中由于文档数量超过100条以后,会超过cursor的默认batach_size,超过batch_size以后需要从mongos拉取更多的数据。
由于lbc->mongos没有使用长连接,有可能会出现这种情况,第一个batch使用了mongos A,取第二个batch时使用了mongos B。
这时候mongos A返回的cursor实际上在mongos B中并不存在,从而抛出了cursorNotFoundException.
解决方案:
1. 使用ip的方式直接连接mongos,也可以配置多个ip,mongodb的驱动会自行解决相关问题
2. 固定lbc在负载均衡时和mongos的链接
-------------更新---------------
根据负载均衡的实现,应用和lbc使用长连接也有可能出错
pymongo使用了连接池,每次请求数据会随机从连接池中获取连接来请求数据,如果lbc是根据连接来做的负载均衡,
那么由于cursor前后两次可能使用不同连接仍然会引起发送到不同mongos,引起CursorNotFound
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment