对于一些Morphia查询asList,我们最终遇到了cursor not found exceptions,我发现了hint on SO,这可能会消耗大量内存.

现在我想了解更多关于背景的信息:sombody能解释一下(英语)游标(MongoDB)到底是什么吗?为什么它能一直开着或者找不到?


文档中的光标如下所示:

指向查询结果集的指针.客户机可以遍历光标来检索结果.默认情况下,游标在不活动10分钟后超时

但这并不是很能说明问题.也许为查询结果定义batch会有所帮助,因为documentation also states:

MongoDB服务器批量返回查询结果.批处理大小将不会超过BSON文档的最大大小.对于大多数查询,第一批返回101个文档,或者刚好足够超过1MB的文档.后续批处理大小为4兆字节.[...] 对于包含没有索引的排序操作的查询,服务器必须加载内存中的所有文档,以便在返回任何结果之前执行排序.

注意:在我们所讨论的查询中,我们根本不使用sort语句,但也不使用limitoffset.

推荐答案

我绝对不是mongodb专家,但我只想补充一下go 年在中型mongo系统中工作的一些观察结果.还要感谢@xameeramir提供了有关游标一般工作方式的精彩演练.

"光标丢失"异常的原因可能有几个.我注意到的一个问题在这个答案中得到了解释.

光标位于服务器端.它不分布在副本集上,而是存在于创建时的主实例上.这意味着,如果另一个实例作为主实例接管,游标将丢失给客户端.如果旧的小学仍然在上面和周围,它可能仍然在那里,但没有用.我猜过一会儿就被垃圾收集起来了.因此,如果您的mongo副本集不稳定,或者前面的网络不稳定,那么在执行任何长时间运行的查询时,您都会运气不佳.

如果游标想要返回的内容的完整内容不适合服务器上的内存,那么查询可能会非常慢.服务器上的RAM需要大于运行的最 bigquery .

通过更好的设计,所有这些都可以部分避免.对于大型长时间运行查询的用例,最好使用几个较小的数据库集合,而不是一个较大的数据库集合.

Mongodb相关问答推荐

MongoDB - 将属性添加到数组中的对象(如果不存在)

如何 db.getUser() 使用 go mongo-driver

mongo:在 mongodb 6.0 docker 容器上找不到命令

通过 _id 更新一个文档(无效的 BSON 字段名称 _id)

Pymongo API TypeError: Unhashable dict

如何使用 Spring Data MongoDB 通过 GridFS ObjectId 获取二进制流

无法连接到mongolab主机

MongoDB获取聚合查询的executionStats

从 MongoDB find() 结果集中识别最后一个文档

MongoDB:设置 Windows 服务

mongod 和 mongo 命令在 Windows 10 上不起作用

如何在 $lookup Mongodb 的 LocalField 中将字符串转换为 objectId

使用 Node.js 和 mongodb 处理超时

NodeJS中的密码重置

try 解析序列化 JSON 字符串时处理 MongoDB 的 ISODate()

是否有支持 MongoDB 和 Devise 的 Rails 管理界面?

指定在 mongodb .js 脚本中使用哪个数据库

Mongoose - 获取 _id 列表而不是具有 _id 的对象数组

如何在java中删除mongodb集合中的所有文档

MongoDB:聚合框架: $match between fields