慢速查询会阻塞快速查询,直到执行慢速查询:MongoDB 使用 NodeJs 驱动程序

Slow query blocks fast queries until slow query gets executed : MongoDB with NodeJs driver

我 运行 很慢 query/aggregate 需要 3 秒以上,然后其他查询被阻止,直到慢查询完成。

执行慢速查询后,仅执行数量等于连接池大小的快速查询,然后所有进一步的操作都将被阻塞,直到执行慢速查询。之后快速查询正常执行。

我正在使用 MongoDB 2.6.7 和 mongodb NodeJs 驱动程序 1.4.30。

慢聚合管道:

[{"$unwind": "$status_history"},{"$sort": {"_id": -1}},{"$limit": 100}]

我在 运行 上面查询了一个包含 10k 文档的集合,展开时会产生 200k 文档,然后 $sort 操作。这大约需要 5-10 秒。

在此之后,任何通常在 100-500 毫秒内执行的简单查询都需要 3-10 秒。

您需要使用适当的索引优化您的查询,因为在 MongoDB 中也有数据库锁定,因此所有查询都会在一段时间内被阻止。 请检查 here

在大多数情况下,将大扫描分解为多个小扫描并加入结果集也有帮助。

此外,如果可能,使用副本集创建分片,以便您可以分发查询

这是我从 MongoBD 支持那里得到的:

poolSize :允许您控制并行打开多少个 tcp 连接。该值的默认值为 5,但您可以根据需要将其设置得尽可能高。驱动程序将使用 循环策略 调度和读取 tcp 连接。

如果连接正忙运行运行缓慢,这可能会阻止后续操作。

有两种可能的解决方法

Increase the connection pool size

如果您无法控制 运行 的查询类型,则在 运行 更长的操作时使用更大的连接池将减少这种情况发生的 likelihood/frequency,尽管仍然有可能一个操作将被阻止,并且随着更多 运行ning 操作的进入,这种可能性会增加。 有了更大的循环池,当再次从池中选择一个连接时,一个长的 运行ning 操作很可能已经完成。

Diverge the possible slower operations into another connection pool

您可以为较慢的操作创建一个单独的连接池(即 MongoClient.connect() 的结果),并让生产池满足快速查询。这将确保 slow/blocking 聚合查询不会冻结用于其他操作的池。 较慢的操作当然很难事先确定,但例如它们可能是使用排序、大限制、跳过或聚合或映射减少操作的查询。