pymongo.errors.CursorNotFound: 游标 id "..." 未找到

Posted

技术标签:

【中文标题】pymongo.errors.CursorNotFound: 游标 id "..." 未找到【英文标题】:pymongo.errors.CursorNotFound: cursor id "..." not found 【发布时间】:2021-12-05 23:17:52 【问题描述】:

我有一个在 AWS 中运行并读取数据库中超过 400k 文档的程序。直到最近它才完美运行。我不确定发生了什么变化,但现在我收到了pymongo.errors.CursorNotFound: cursor id "..." not found

我尝试研究,似乎是与数据库的连接问题,但我没有更改任何内容。

下面是堆栈跟踪:

Text Analysis Started....
DB Connection init...
Traceback (most recent call last):
  File "predict.py", line 8, in <module>
    textanalyser.start()
  File "/usr/src/app/text_analyser.py", line 100, in start
    for row in table_data:
  File "/usr/local/lib/python3.7/site-packages/pymongo/cursor.py", line 1156, in next
    if len(self.__data) or self._refresh():
  File "/usr/local/lib/python3.7/site-packages/pymongo/cursor.py", line 1093, in _refresh
    self.__send_message(g)
  File "/usr/local/lib/python3.7/site-packages/pymongo/cursor.py", line 955, in __send_message
    address=self.__address)
  File "/usr/local/lib/python3.7/site-packages/pymongo/mongo_client.py", line 1346, in _run_operation_with_response
    exhaust=exhaust)
  File "/usr/local/lib/python3.7/site-packages/pymongo/mongo_client.py", line 1464, in _retryable_read
    return func(session, server, sock_info, slave_ok)
  File "/usr/local/lib/python3.7/site-packages/pymongo/mongo_client.py", line 1340, in _cmd
    unpack_res)
  File "/usr/local/lib/python3.7/site-packages/pymongo/server.py", line 136, in run_operation_with_response
    _check_command_response(first)
  File "/usr/local/lib/python3.7/site-packages/pymongo/helpers.py", line 156, in _check_command_response
    raise CursorNotFound(errmsg, code, response)
pymongo.errors.CursorNotFound: cursor id 3011673819761463104 not found

您能提供的任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

这是 MongoDB 中非常常见的问题。我将首先详细说明该问题,然后为您提供可能的解决方法。

每当您在 MongoDB 上执行查找或聚合操作时,它都会向您返回一个游标,该游标将分配给它一个唯一的游标 ID。此光标将有一个截止日期,在几分钟不活动后它将被删除。这样做是为了节省运行 MongoDB 的机器的内存和 CPU 使用率。游标返回的最大文档为 16MB 或 MongoDB 配置文件中设置的值。

假设您在配置了 10 分钟游标空闲超时的 MongoDB 服务器中执行一次查找操作,其中包含 100 条记录中的 100 条记录。如果处理 300 - 400 个文档的时间超过 10 分钟,则该游标将终止,您将无法获得 400 - 500 个批处理文档,因为它无法匹配该 ID。

不过,解决方法很少。

解决方法 - 1:

您可以为查找命令设置无光标超时选项no_cursor_timeout=True

注意:别忘了把光标结束

cursor = col.find(, no_cursor_timeout=True)
for x in cursor:
  print(x)

cursor.close()  # <- Don't forget to close the cursor

解决方法 - 2:

此外,将批量大小限制为较小的数量batch_size=1

这样做是以 10 个为一组发送文档,覆盖默认值。

cursor = col.find(, no_cursor_timeout=True, batch_size=1)
for x in cursor:
  print(x)

cursor.close()  # <- Don't forget to close the cursor

【讨论】:

我不明白这是 2 种变通方法还是 2 步变通方法。 batch_size=1 是否将批量大小设置为 10,或者是拼写错误?没有no_cursor_timeout 选项的有限批量大小会起作用吗? 这是两种不同的解决方法,但我建议您同时使用它们。 no_cursor_timeout 有一个覆盖设置我的 mongod 实例。 batch_size=1 是一个示例,每个请求发送一个文档。您应该将此值调整为 10 或 20,具体取决于通过光标迭代处理每个文档所花费的数量和时间。

以上是关于pymongo.errors.CursorNotFound: 游标 id "..." 未找到的主要内容,如果未能解决你的问题,请参考以下文章