MongoDB、NUMA 硬件、页面错误但有足够的 RAM 用于工作集、触摸命令或 vmtouch/dd 未加载到内存中

Posted

技术标签:

【中文标题】MongoDB、NUMA 硬件、页面错误但有足够的 RAM 用于工作集、触摸命令或 vmtouch/dd 未加载到内存中【英文标题】:MongoDB, NUMA hardware, page faults but enough RAM for working set, touch command or vmtouch/dd does not load into memory 【发布时间】:2013-11-15 07:31:11 【问题描述】:

MongoDB 2.46 和 2.4.8

用例:

    在具有 2 个索引的集合上加载 100.000 个文档。常驻内存增加 (mongostat),并且不会发生页面错误。 重启 mongod。常驻内存不足(这是意料之中的) 尝试使用 touch command db.runCommand( touch: collection, data: true, index: true ) 或其他方式“预热”mongo(在 OS 上,vmtouch / dd)a) 在这一步中,在我的开发机器 (MacOS) 上,我在 mongostat 中看到很多页面错误试图加热它(预期的)并且驻留内存被提升。从那时起,任何更新都不会引发页面错误b)在 numa 服务器(256 GB RAM)上,即使我使用本指南启动 mongo:http://docs.mongodb.org/manual/administration/production-notes/#mongodb-on-numa-hardware(注意:我没有超级用户访问权限。但是,第二步,在 /proc/sys/vm/zone_reclaim_mode 中回显 0,已经是 0,所以我就这样离开了),我似乎无法用“触摸”命令。没有任何反应,即使它成功返回。 在mongostat中,只有'mapped'和'vsize'越来越高,驻留内存一样(35m)。我什至尝试使用 vmtouch 和 dd 命令加载操作系统内存中的数据文件。 只有重新索引集合会改变常驻内存。

问题是在我开始将数据加载到服务器后一段时间开始的。我做了很多 upserts,一开始的性能很棒(3000 - 4000 upserts/sec)。这是意料之中的,因为工作集将能够放入内存中。在 30.000.000 个文档之后,该过程似乎产生了很多页面错误,我不知道为什么。 数据文件约为。 33GB,性能约为 500 upserts/sec,有很多页面错误。这应该意味着工作集不在内存中。但是,256GB RAM 应该绰绰有余。我尝试了 'touch' 命令,但常驻内存很低(我什至重新启动了 mongod 进程,运行了 touch 命令,即使 'mapped' 和 'vsize' 飙升到很多 GB,常驻内存仍然很低,35m) .我试图重新索引集合,瞧,常驻内存从 35m -> 20GB。但是,我再次看到页面错误。然后我尝试 vmtouch 数据文件(或使用 dd)。同样,很多页面错误。

问题是我不能“仅”500 次更新/秒。我应该改变我的应用程序逻辑吗?我认为使用 256GB 内存,我的“活动”工作集(预计为 60GB)应该适合内存。我在中间(30GB),似乎我无法解决这个问题。是numa硬件吗?我是否应该进行任何其他更改?

提前致谢

【问题讨论】:

此外,我相信在 mongod 实际读取它之前它不会显示为 resident,这是我从这里得到的一种线索:groups.google.com/forum/#!topic/mongodb-user/UfQoyllDNGU,我知道它只与 serverStatus 有关,但我认为这里同样适用 但是,在我的开发机器 (MacOS) 上,当我对数据和索引进行“触摸”时,常驻内存会增加。在服务器上没有。此外,在您评论的谷歌群组问题中,那里的用户声明在“触摸”命令之后,常驻内存为 5821MB。就我而言,常驻内存约为 35-90MB。有了 33GB 数据,我预计应该会更多 不幸的是,由于我对硬件(超级用户)没有特殊访问权限,所以我无法找到它。除非有其他方法。但是,我没有看到任何类似的警告:** WARNING: Readahead for .. 设置为 512KB **,所以我认为预读没问题,否则我会在日志中收到警告 收集统计数据为: "ns" : "cortexDay.accumulatedData", "count" : 36425904, "size" : 24786208048, "avgObjSize" : 680.4555364775573, "storageSize" : 27372449648, "numExtents" : 33, "nindexes" : 2, "lastExtentSize" : 2146426864, "paddingFactor" : 1.0000000027731564, "systemFlags" : 0, "userFlags" : 0, "totalIndexSize" : 2320741248, "indexSizes" : "_id_" : 1063713952, "d_1_m_1" : 1257027296 , "ok" : 1 (正在尝试格式化,抱歉) 我是这么认为的,但我不知道为什么以及如何解决这个问题。只有其他选项(如果我不能解决这个问题),会是虚拟机吗?我想不出别的了。 【参考方案1】:

我刚刚在 ServerFault 上写了一个pretty detailed answer,内容涉及驻留内存、页面错误以及如何进行故障排除、调整和调整等,所以我不会在这里重新讨论。

我会说,Sammaye 的评论是正确的,touch(或 dd、vmtouch 等)命令不会导致内存被报告为驻留再次mongod 进程,直到进程实际访问数据(直到它是仅在 FS 缓存中),然后您可以在SERVER-9415 中遇到问题,这可能会导致常驻内存报告不足。

我认为您已经在这里查看了关键指标,并且您应该能够获得比您报告的更高的常驻内存(或者至少,将更多数据放入内存而不会出现明显的页面错误)。您所描述的情况听起来像是来自其他地方的内存压力,但我假设您会注意到另一个进程正在消耗大量内存。

我要指出的是,我之前花了几天时间(字面意思)试图使特定的 AWS 实例超过 30% 的内存阈值,但没有成功。

当我们最终放弃并尝试另一个实例时,没有改变任何东西(我们只是添加了一个新实例作为辅助实例并故障转移到它),它立即达到了 70% 以上的常驻内存。当然,那是在 m2.4xlarge 实例上,所以与您的规模不同,但始终值得牢记。如果您可以在其他实例上尝试一下,我建议您试一试。

【讨论】:

以上是关于MongoDB、NUMA 硬件、页面错误但有足够的 RAM 用于工作集、触摸命令或 vmtouch/dd 未加载到内存中的主要内容,如果未能解决你的问题,请参考以下文章

mongodb的NUMA问题

sparklyr中的堆空间不足,但有足够的内存

NUMA 在虚拟内存中是如何表示的?

Mongodb 使用numactl 启动

MongoDB服务器CPU一直很高,最高达到900%,可能是哪些原因?

为啥使用 numa_alloc_onnode() 进行分配会导致“页面不存在”?