【问题标题】:pymongo.errors.CursorNotFound: cursor id "..." not foundpymongo.errors.CursorNotFound: 游标 id "..." 未找到
【发布时间】: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

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

【问题讨论】:

    标签: python-3.x mongodb pymongo


    【解决方案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,具体取决于通过光标迭代处理每个文档所花费的数量和时间。
    猜你喜欢
    • 2018-11-18
    • 1970-01-01
    • 1970-01-01
    • 2020-04-10
    • 2018-03-07
    • 1970-01-01
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多