当MongoDB数据库大小超过RAM的倍数时会发生什么?

14

它会变慢吗?只处理适合内存的数据? 如果MongoDB的索引超过RAM会发生什么?

2个回答

16

编辑:此回答不再适用(MongoDB有了新的存储引擎,不再以这种方式运行),该答案非常陈旧,mmapv1存储引擎已弃用。

关于Mongo

MongoDB使用内存映射文件。

这意味着操作系统基本上控制着何时将数据从内存中分页进出(到磁盘)。

规则

如果索引和工作集大小超过内存容量,则最近最少使用的页面(内存部分)将被刷新到磁盘。这样就只会保留最近使用的能够轻松放入内存的数据。

您的操作系统控制这一点。

虽然如果真正的工作集和索引不符合内存容量时,性能会很差,但在实际情况下,一个人的工作集(热数据)的大小远小于他们的总数据集。

如果不违反此规则,即使索引和总数据可能超过可用内存的总量,大多数时间您的性能都应该很好。

如何运作

如果执行需要不在内存中的数据的查询,则会将其换入内存(从磁盘检索),并且会出现性能下降。

注意:这基本上是在首次启动数据库(冷启动)时的情况。

一开始没有任何数据在内存中,需要数据时会发生页错误,并根据需要将数据分页到内存中。当内存不足时,最近最少使用的页面(块)被刷新出内存,以便保留更热(最近访问)的数据。

此外值得一提的是,由于索引经常被使用,因此始终是最近使用过的,它们几乎永远不会被换出。


我不同意“您仍将体验相对较高的性能”的说法。根据我的经验,如果索引大小接近或超过RAM大小,则性能会急剧下降。 MongoDB 网站建议您保持索引大小<< RAM 大小。 - Ian Mercer
如果我说工作集+索引在内存中时性能良好,那么很显然,如果你的索引甚至都放不下内存,那么你的工作集就没有太多空间了,会脱离“你将经历高性能”的范畴,难道我错了吗? - Tyler Brock
你的回答是... "如果你的索引+工作集超出内存限制,..." 并继续说道 "除非你不断地触碰数据集中的每个部分,否则你仍然会体验到相当高的性能。" 这是具有误导性的部分—一旦索引大于RAM,你并不需要触碰太多内容就会遇到可怕的性能问题。 - Ian Mercer
是的,因为在你耗尽内存用于工作集和索引之前,你肯定会遇到内存不足仅用于索引的情况。如果你的工作集没有全部在内存中,那么它将在索引之前被分页出去,这时你已经失败了。除非你所做的每个查询都是在一个覆盖索引上进行的,否则你会在数据库中的任何情况下都会遇到死水线,而不必担心只有索引适合内存的问题。 - Tyler Brock

6
如果索引大于可用的RAM,则性能会迅速下降。MongoDB网站特别建议您“确保索引可以适合RAM”。如果查询似乎不太流畅,您应该验证您的索引是否足够小以适合RAM。例如,如果您正在运行4GB RAM,而有3GB的索引,则您的索引可能不适合RAM。您可能需要添加RAM和/或验证您创建的所有索引是否实际使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接