MongoDB搜索进程(mongot) 在固定执行池中运行查询。当查询到达的速度超过进程运行它们的速度时, Atlas会将多余的查询保存在准入控制队列中,而不是立即运行所有查询。搜索减载控制此队列。它可以保护搜索进程免受内存耗尽的影响,也可以防止因进程接受的并发工作超过其完成能力而导致的延迟崩溃。
搜索减载适用于 $search 和 $vectorSearch 查询。它在运行MongoDB 8.0、8.3 和 9.0 或更高版本的集群上可用,并且Atlas在运行MongoDB 9 的集群上默认启用它。0或更高版本。
当搜索进程达到其执行容量时, Atlas会对传入的查询进行排队。排队查询在容量释放时运行,因此它们会成功完成,但延迟会比平常更高。延迟会保持较高水平,直到到达速率降至进程可以接受工作的速率以下。
在任何时候,查询都在执行池中运行、在准入控制队列中等待或被拒绝。只有队列已满才会导致拒绝。
搜索减负载不会改变搜索进程同时运行的查询数量。它仅会更改准入控制队列是否具有容量限制:
通过无界队列, Atlas对每个超额查询进行排队。查询始终运行,但持续的过载会导致延迟增加。
使用有界队列, Atlas仍会对多余的查询进行排队,但最多达到容量限制。当队列已满时, Atlas会立即拒绝进一步的查询,而不是为每个客户端增加延迟。
Atlas在内部设置执行池的大小和有界队列的容量,并且可以随时更改这些限制。
Atlas承认,当Atlas开始拒绝查询时,过载已经增加了查询的延迟。拒绝可以减轻多余的负载,从而防止延迟进一步下降。它还使搜索进程保持响应,而不是让它完全失败。
已拒绝的查询错误
当Atlas由于准入控制队列已满而拒绝查询时,查询会失败并显示以下错误:
字段 | 值 |
|---|---|
错误代码 |
|
代码名称 |
|
错误标签 |
|
每个支持搜索减载的版本都会返回相同的错误,因此您的应用程序可以依赖于单个错误契约。
重要
被拒绝的查询不可重试
489 错误不带有 RetryableError 标签。 MongoDB驱动程序和 mongod 都不会自动重试被拒绝的查询。您的应用程序必须决定如何响应。
拒绝意味着搜索进程已经饱和。重试会立即向无法吸收负载的进程增加负载,从而扩大过载并增加拒绝次数。要响应 489 错误,应用以下做法:
捕获
SystemOverloadedError标签而不是匹配错误消息文本。请等待,然后再次发送查询。使用带抖动的指数退避算法,以便并发客户端不会彼此同步重试。
限制尝试次数。向最终用户显示降级结果或错误,而不是无限期地重试。
在拒绝仍然存在的情况下,降低应用程序发送搜索查询的速率。降低客户端并发性可缩短过载时间。
将持续拒绝视为容量信号而不是暂时性故障,并扩展或优化搜索工作负载。
监控并减少搜索过载
Atlas在导致拒绝之前报告排队,这让您有时间采取行动。使用以下信号:
Search Process Throttling 指标报告搜索进程发出信号表示其已超过队列阈值的速率。持续的非零值意味着工作到达的速度比进程允许的速度快。要查看此指标,请参阅查看MongoDB搜索指标。
要减少搜索进程的负载,请执行以下操作:
随着时间的推移分散查询,而不是批量发送。
优化您的查询。添加筛选器,减少前导通配符和深层嵌套子句,并仅返回所需的字段。
配置查询卸载
为每个集群配置搜索减载。该设置接受以下状态:
州 | API Value | 说明 |
|---|---|---|
Atlas 托管 | 无覆盖 | Atlas会根据集群运行的MongoDB版本选择状态。 Atlas在MongoDB 8.0 和 8.3 上将此状态解析为 Off,在MongoDB 9.0 或更高版本上将此状态解析为 On。 |
On(开启) |
| 准入控制队列是有界的。 Atlas对超额查询进行排队直至达到容量限制,然后在队列已满时拒绝进一步的查询,并显示 |
关闭 |
| 准入控制队列没有限制。 Atlas会对每个多余的查询进行排队,并且从不拒绝查询。 |
使用Atlas用户界面或Atlas Administration API更改状态。