php - MongoDB 和 PHP 库游标超时

标签 php mongodb php-mongodb

使用MongoDB官方PHP库(https://docs.mongodb.com/php-library/master/tutorial/install-php-library/)时,如何将游标超时设置为无限?我阅读了混合文档,通常很难理解它是指旧的 PHP 驱动程序还是新的(我正在谈论的)。

例如:

$cursor = $col->find();
foreach ($cursor as $document) {
   // slow code..
}

如何防止游标超时(参见下面的错误)并确保游标随后关闭而不会出现任何内存泄漏?

Fatal error: Uncaught MongoDB\Driver\Exception\RuntimeException: 
cursor id 123456789 not found in /var/www/html/code.php:1

这里有一些类似的问题(例如 this ),但似乎我们缺乏明确的引用。

最佳答案

cursor id 123456789 not found in /var/www/html/code.php:1

这通常是因为应用程序在 getMore 命令之间花费的时间太长。换句话说,游标在第一次迭代时返回许多记录,并且循环需要很长时间才能请求更多记录。

$cursor = $collection->find( [ 'field' => 'foobar'] );
foreach ($cursor as $document) {
    // long running processes (slow)
}

游标在服务器上有超时时间,大约 10 分钟后,如果客户端未向服务器发送任何命令,游标将因不活动而关闭。在上面的情况下,当它请求下一个批处理时,游标已被终止,导致错误消息找不到游标id

有些人尝试通过在光标上设置 noCursorTimeout:true 来禁用光标超时。尽管不建议这样做,因为当从服务器返回的 getMore 结果出现问题时,您最终可能会得到一个永远存在的游标(僵尸)。即,具有 noCursorTimeout 的游标可能在客户端断开连接后很长一段时间内在服务器上保持事件状态。

有几种可能的解决方案:

  • 减少 cursor.batchSize() 。这是因为减少每批的记录数会减少游标不活动状态。即以前 15 分钟处理 100 条记录,现在 7.5 分钟只处理 50 条记录。

  • 手动创建 session ,即 PHPLIB MongoDB\Client::startSession() 。然后将其作为查询的 session 选项传递。在长时间运行的迭代期间,定期使用同一 session (即 ping 服务器)执行一些其他数据库交互。这将使 session 保持事件状态(30 分钟超时);但是,它不会使光标保持事件状态,因此您可以将其与 noCursorTimeout 结合使用。

关于php - MongoDB 和 PHP 库游标超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51790279/

相关文章:

php - 存储数据库,同时访问的良好模式

php - 如何在 php 中对来自 mysql 的多个结果进行编码...我得到 5 个结果,但是当我运行 API 时,它没有显示任何 JSON 格式的数据

php - 需要 Google 地理编码返回英文城市名称

java - 如何计算 Blade 批量尺寸

mongodb - Mongo 聚合不使用索引

javascript - 从文本字段获取值以另存为 PDF

javascript - Mongoose 自动增量

mongodb - 本地字段和外部字段的查找管道内的项目不起作用

php - Laravel Eloquent 地如何从集合中加载和获取单独数组中的关系