将整个索引放在内存/内存中是否足够,或者 mongodb 甚至尝试分配尽可能多的内存来存储数据以进行快速读取?
我想运行 mongodb + 其他应用程序,看起来 mongodb 是唯一一个不允许我定义 RAM 范围的应用程序,比如说“max_memory_allocated_or_reserved=8GB”。
如果没有办法这样做,我应该向 oom-killer 解释 mongod 是“坏”过程,在我看来这不是最佳实践......
将整个索引放在内存/内存中是否足够,或者 mongodb 甚至尝试分配尽可能多的内存来存储数据以进行快速读取?
我想运行 mongodb + 其他应用程序,看起来 mongodb 是唯一一个不允许我定义 RAM 范围的应用程序,比如说“max_memory_allocated_or_reserved=8GB”。
如果没有办法这样做,我应该向 oom-killer 解释 mongod 是“坏”过程,在我看来这不是最佳实践......
你不能按照你的要求做的真正原因(限制内存)是因为 MongoDB 不直接管理它使用的内存 - 它让操作系统来做。MongoDB 只是内存映射其所有数据,然后让操作系统根据需要将其分页进出内存。因此,在 MongoDB 以完全不同的方式实现这一点或操作系统允许之前,无法直接管理可能的使用量(自 2.4 天以来在 Linux 中不可能)。
目前唯一能真正做到资源隔离的方法是使用虚拟化方案,将MongoDB隔离在自己的VM中。是的,这涉及到一些开销(尽管管理程序已经变得更好了),但目前这是为这种级别的资源控制付出的代价。
就 OOM Killer 而言,即使主机上没有其他进程,只要您的数据集和索引总体超过可用内存,MongoDB 就可以遇到 OOM Killer 问题。这是因为数据是如何从内存中分页出来的——如果没有内存压力(没有其他东西需要常驻内存),并且您不断添加/接触新数据和索引,那么最终它将增长到消耗所有可用的 RAM。因此,建议在运行 MongoDB 时始终配置一些交换:
https://docs.mongodb.com/manual/administration/production-notes/#swap
当然,LRU 数据将首先被分页,其他进程也可以占用 res mem,但是这个概念仍然适用,除非您将数据集加载到内存中然后它保持静态。如果您担心,最好的办法是将其放入 MMS 并随着时间的推移跟踪使用情况:
http://mms.mongodb.com
更新:2015 年 8 月
自从我写了这个答案以来,事情已经发生了一些变化,信息有点过时了。例如,Linux 现在拥有cgroups和相关技术(例如Docker 容器),它们已经成熟到可以让您更好地隔离和限制生产环境中任何进程消耗的资源(包括内存),即使是使用像 MongoDB 这样的内存映射。
此外,随着 MMAP 之外的新存储引擎(如 MongoDB 3.0+ 中的 WiredTiger)的出现,您可以使用内置功能来限制 MongoDB 的缓存大小。因此,RAM 需求现在确实取决于您选择如何配置 MongoDB、运行它的环境以及选择的存储引擎。
MongoDB 将使用可用的空闲内存进行缓存,并根据需要交换到磁盘,以便为同一服务器上的其他应用程序提供内存。为了获得最佳性能,您需要有足够的 RAM 来将索引和常用数据(“工作集”)保存在内存中。
有用的阅读:
多年来,MongoDB 发生了一些变化。
TL;博士
如果在 MongoDB 上使用 MMAPv1 存储引擎,
working set
大小必须适合RAM。 https://docs.mongodb.com/manual/faq/diagnostics/#must-my-working-set-size-fit-ram如果在 MongoDB 上使用 WiredTiger 存储引擎,则无需关心 RAM 是否
working set
适合。 https://docs.mongodb.com/manual/faq/diagnostics/#memory-diagnostics-for-the-wiredtiger-storage-engine