MongoDB - 如何减少 numYields

How*_*Lee 5 mongodb

我有一个大约 100GB 数据大小的 MongoDB 数据库。我用 300 个线程运行了一个测试,查询都是读取,没有写入(我猜除了写入数据库分析器)。我启用了数据库分析器来跟踪慢查询。我注意到具有高 'numYields' 的查询导致高 'millis';同样,低 numYields 的查询在低毫秒内响应非常快。

90% 的查询运行速度非常快,在 1 ~ 2 毫秒内,但是,大约 2% 的查询以 60,000 毫秒或更高的速度结束。

根据 MongoDB 文档:

numYields 是一个计数器,用于报告操作允许其他操作完成的次数。

通常,操作会在需要访问 MongoDB 尚未完全读入内存的数据时产生。这允许在 MongoDB 为让步操作读取数据时,其他在内存中有数据的操作可以快速完成。

我知道一个慢查询试图从磁盘读取数据,同时让步给内存中已经有数据的其他查询。但是,如果这导致该特定查询的 60,000 毫秒,则变得不合理。

也许有办法限制 numYields?或者也许尝试将所有内容都放在内存中?有什么建议?

Ada*_*m C 9

这是一个常见的误解,即收益率在某种程度上导致了缓慢。事实上,它们是一种症状,而不是原因。即使没有需要让出(基本上是写)的锁争用,查询在必须从磁盘分页时仍然让出。然后,当完成一定数量的分页时,他们重新获取锁,并在需要更多分页时再次寻求让步(重复直到完成)。如果写入没有锁争用,那么这几乎是即时的,不会增加整体执行时间。

如果一个查询产生很多,那么它会大量访问磁盘,这就是缓慢的原因 - 磁盘访问。因此,numYields这只是一种推断确实是分页到磁盘导致查询变慢的方法。如果您希望这些查询速度快,那么您需要将该数据集保存在内存中,并有足够的内存使其能够长期保留而不会被驱逐。

注意:默认情况下,内核将使用LRU来决定哪些被驱逐,因此缓慢的可能候选对象是对不经常访问的数据集(大)部分的查询。

没有办法限制numYields,这样做也没有意义,但是补救措施是识别那些慢查询所寻址的数据并使其适合内存(注意:对任何数据的第一个查询都将除非您以某种方式预热,否则仍然很慢,第二个查询将在内存中并且很快)。