MongoDB: RAM requirements

将整个索引存储在内存/RAM中是否足够,或者MongoDB是否尝试分配尽可能多的RAM来存储数据以实现快速读取?

我想运行MongoDB和其他应用程序,但似乎只有MongoDB不允许我定义一定范围的RAM,比如"max_memory_allocated_or_reserved=8GB"。

如果没有办法这样做,我应该向oom-killer解释mongod是一个"糟糕"的进程,不符合最佳实践,这是我的观点...

3个回答

你无法按照你的要求(限制内存)的真正原因是因为MongoDB不直接管理它使用的内存 - 它让操作系统来管理。MongoDB只是将所有数据进行内存映射,然后由操作系统根据需要将其分页进出内存。因此,在MongoDB以完全不同的方式实现此功能之前,或者操作系统允许此功能(自2.4版本以来在Linux上不可能),无法直接管理所使用的内存量。
目前唯一真正隔离资源的方法是使用虚拟化解决方案,并将MongoDB隔离在自己的虚拟机中。是的,这会带来一些开销(尽管虚拟化监视程序已经变得更好了),但目前这是为了获得那种级别的资源控制而必须付出的代价。
至于OOM Killer,在主机上没有其他进程的情况下,只要数据集和索引总体上超过可用内存,MongoDB就可能遇到OOM Killer问题。这是因为数据如何从内存中分页出去 - 如果没有内存压力(没有其他进程需要Resident内存),并且您不断添加/触及新数据和索引,那么最终它将增长到占用所有可用的RAM。因此,在运行MongoDB时建议始终配置一些交换空间。

https://docs.mongodb.com/manual/administration/production-notes/#swap

当然,LRU数据将首先被分页出去,其他进程也可以占用剩余的内存空间,但这个概念仍然适用,除非你将数据集加载到内存中并保持静态状态。如果你担心的话,最好的办法是将其放入MMS并随着时间跟踪使用情况。

http://mms.mongodb.com

更新:2015年8月

自从我写下这个答案以来,情况有所变化,信息有点过时。例如,Linux现在已经拥有cgroups和相关技术(例如Docker容器),这些技术已经成熟到可以更好地隔离和限制生产环境中任何进程消耗的资源(包括内存),即使是像MongoDB这样使用内存映射的进程。

此外,随着MongoDB 3.0+引入了超越MMAP的新存储引擎,如WiredTiger,您可以使用内置功能限制MongoDB的缓存大小。因此,现在的RAM需求确实取决于您选择如何配置MongoDB、运行环境以及选择的存储引擎。


关于WiredTiger:“storage.wiredTiger.engineConfig.cacheSizeGB只限制WiredTiger缓存的大小,而不是mongod使用的总内存量。WiredTiger缓存仅是MongoDB使用的RAM的一个组件。MongoDB还通过文件系统缓存自动利用机器上的所有空闲内存...” - Stefan Rogin
没错,但同样可以说对于任何将数据从磁盘分页的应用程序来说都是如此。文件系统缓存不再是数据的主要缓存方法,就像在MMAP存储引擎中使用内存映射文件时那样。 - Adam C


多年来,MongoDB发生了一些变化。
简而言之:
如果在MongoDB上使用MMAPv1存储引擎,则工作集的大小必须适合RAMhttps://docs.mongodb.com/manual/faq/diagnostics/#must-my-working-set-size-fit-ram 如果在MongoDB上使用WiredTiger存储引擎,则不需要担心RAM是否适合工作集https://docs.mongodb.com/manual/faq/diagnostics/#memory-diagnostics-for-the-wiredtiger-storage-engine

WiredTiger存储引擎的内存诊断

我的工作集大小必须适应RAM吗?

不需要。

如何计算我应用程序所需的RAM量?

使用WiredTiger,MongoDB同时利用了WiredTiger内部缓存和文件系统缓存。

从版本3.2开始更改:从MongoDB 3.2开始,默认情况下,WiredTiger内部缓存将使用以下两者中较大的一个:

RAM的60%减去1 GB,或者1 GB。


嗯,这个答案帮助不大,也不是特别准确。 - Philip Schiff