我在我的 mongostat 输出中看到了一个巨大的(~200++)故障/秒数,尽管锁定百分比非常低:
我的 Mongo 服务器在亚马逊云上的 m1.large 实例上运行,因此它们每个都有 7.5GB 的 RAM ::
root:~# free -tm
total used free shared buffers cached
Mem: 7700 7654 45 0 0 6848
显然,我没有足够的内存来满足所有 cahin mongo 想要做的事情(顺便说一句,由于磁盘 IO,导致 CPU 使用率很高)。
我发现这个文档表明在我的场景中(高故障,低锁定百分比),我需要“横向扩展读取”和“更多磁盘 IOPS”。
我正在寻找有关如何最好地实现这一目标的建议。也就是说,我的 node.js 应用程序执行了很多不同的潜在查询,我不确定瓶颈发生在哪里。当然,我试过
db.setProfilingLevel(1);
但是,这对我没有多大帮助,因为输出的统计信息只是显示我的查询速度很慢,但我很难将这些信息翻译成查询导致页面错误的信息......
如您所见,这导致我的 PRIMARY mongo 服务器上的 CPU 等待时间很长(几乎 100%),尽管 2x SECONDARY 服务器不受影响......
以下是 Mongo 文档对页面错误的评价:
页面错误表示 MongoDB 需要不在物理内存中的数据,并且必须从虚拟内存中读取的次数。要检查页面错误,请参阅 serverStatus 命令中的 extra_info.page_faults 值。此数据仅在 Linux 系统上可用。
单独的页面错误很小并且很快完成;然而,总的来说,大量的页面错误通常表明 MongoDB 从磁盘读取了过多的数据,并且可以表明许多潜在的原因和建议。在许多情况下,MongoDB 的读锁会在页面错误后“让出”以允许其他进程读取并避免在等待下一页读入内存时阻塞。这种方法提高了并发性,在大容量系统中,这也提高了整体吞吐量。
如果可能,增加 MongoDB 可访问的 RAM 量可能有助于减少页面错误的数量。如果这不可行,您可能需要考虑部署一个分片集群和/或在您的部署中添加一个或多个分片以在 mongod 实例之间分配负载。
所以,我尝试了推荐的命令,这非常无用:
PRIMARY> db.serverStatus().extra_info
{
"note" : "fields vary by platform",
"heap_usage_bytes" : 36265008,
"page_faults" : 4536924
}
当然,我可以增加服务器大小(更多 RAM),但这很昂贵,而且似乎有点矫枉过正。我应该实现分片,但我实际上不确定哪些集合需要分片!因此,我需要一种方法来隔离故障发生的位置(哪些特定命令导致故障)。
谢谢您的帮助。