MongoDB 和 PHP 库游标超时

MongoDB and PHP Library Cursor Timeout

在使用官方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

这里有一些类似的问题(比如),但似乎我们缺乏明确的参考。

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

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

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

游标在服务器上超时,大约 10 分钟后,如果客户端未向服务器发送任何命令,它将因不活动而关闭。在上面的例子中,当它请求下一批时,游标被杀死导致错误消息 cursor id not found.

有些人试图通过在游标上设置 noCursorTimeout:true 来禁用游标超时。虽然不推荐这样做,因为当从服务器返回的 getMore 结果出现问题时,您可能会得到一个永远存在的游标(僵尸)。即带有 noCursorTimeout 的游标可能在客户端断开连接后很长时间内在服务器上保持活动状态。

有几个可能的解决方案:

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

  • 手动创建会话,即 PHPLIB MongoDB\Client::startSession(). Then pass this as a session option on the queries. At regular intervals during the long-running iteration, perform some other database interaction using the same session i.e. ping 服务器。这将使 session 保持活动状态(30 分钟超时);但是,它不会使光标保持活动状态,因此您可以将其与 noCursorTimeout 结合使用。