@angela,@Asya,非常感谢帮助我的。
事实证明延迟的主要原因是MongoDB的GLOBAL LOCK
本身。我们的锁定百分比平均为5%,有时高达30-50%,导致查询速度缓慢。
如果您遇到了这个问题,您需要做的第一件事情就是启用mongodb MMS服务(mms.10gen.com
),这将为您提供很多关于您的数据库服务器中究竟发生了什么的见解。
在我们的情况下,LOCK百分比非常高,确实是给它的多个原因。首先你需要做的就是读取并行的mongodb文档, http://docs.mongodb.org/manual/faq/concurrency/
锁定的原因可以在应用程序级别,mongodb或硬件。
1)我们的应用程序是做了很多的updates
和每次更新(比100 ops/sec
更多)持有MongoDB中一个global lock
。问题是,当一个不在内存中的条目发生更新时,mongo将不得不首先将数据加载到内存中,然后更新(在内存中),整个过程发生在global lock
内部。如果说整件事情需要1秒才能完成(0.75sec
从磁盘加载数据并且0.25sec
在内存中更新),则整个剩余的更新调用将等待(对于整个1 sec
)并且此类更新开始排队......并且你会注意到你的应用服务器上越来越慢的请求。
在制作update
之前,对于它的解决方案(虽然听起来可能很愚蠢)是针对相同数据的query
。它有效地做是“加载数据到内存”移动(0.75sec)部分出global lock
这大大降低了您的lock percentage
2)其他主要的全球锁的原因是MongoDB的数据flush
到磁盘中。基本上每60秒(或更少)mongodb(或OS)将数据写入磁盘,并在此过程中持有global lock
。 (这有点解释了随机缓慢的查询)。在您的MMS统计中,请参阅background flush avg
的图表...如果它很高,那意味着你必须获得更快的磁盘。
在我们的例子中,我们在EC2
移动到新的EBS optimized
实例,还碰到了从100
到500
几乎减半background flush avg
和服务器非常愿意现在设置IOPS
。
请问您在同一个mongod进程中执行的其他操作是否会导致整体缓慢?如果可能的话,从日志文件中看到更多内容会很有帮助。另外,你应该尝试运行Dex。 Dex是一个开源工具,用于查看缓慢的查询并推荐索引(http://mongolab.org/#view=dex)。 – angela 2013-03-16 07:53:02
另外,您应该查看http://docs.mongodb.org/manual/administration/production-notes/上关于MongoDB的生产笔记文档。例如,您应该使用ext4或xfs装入卷,并确保关闭一次。 – angela 2013-03-16 07:56:14
毫无疑问,此查询使用索引,因此Dex不太可能提供帮助。然而,关于你的MongoDB实例在做什么的问题是相关的。例如,你在写很多东西吗?偶尔缓慢的查询可能与冲洗时相吻合。 (a)更多信息(b)在MongoDB用户谷歌群组上询问此问题。 – 2013-03-16 15:24:39