我在mongodb
实例(7GB RAM)上安装了EC2
(版本:2.0.8),数据大小仍然小于1GB
。我正在使用配置的100 IOPS
磁盘来提高磁盘性能。
问题是,我得到了一些随机的慢速查询,如下所示(来自mongo日志)
db.UserInfoShared查询:{_ id:“999081873179”} ntoreturn:1 idhack:1 reslen:108 1919ms
差点儿2 secs
!
这只是一个_id
查询集合,其中大约100,000
个条目的大小都小于500 bytes
。该实例只有mongo在其中运行,通常这样的查找只需要0.01 sec
。
可能的原因是什么?我应该尝试解决这个问题?非常感谢任何帮助...
答案 0 :(得分:3)
@angela,@ Asya,非常感谢你帮助我。
事实证明,延迟的主要原因是mongodb GLOBAL LOCK
本身。我们的锁定百分比平均为5%,有时达到30-50%,这导致查询速度缓慢。
如果您遇到此问题,首先要做的就是启用mongodb MMS服务(mms.10gen.com
),这将为您提供有关数据库服务器中发生的具体情况的大量见解。
在我们的案例中,LOCK PERCENTAGE非常高,并且有多种原因。你需要做的第一件事就是阅读有关并发性的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
})并且此类更新开始排队......您会发现应用服务器中的请求越来越慢。
在制作query
之前,针对相同数据的解决方案(尽管可能听起来很愚蠢)是update
。它实际上做的是将'加载数据移动到内存'(0.75秒)部分移出global lock
,这大大减少了lock percentage
2)全局锁定的另一个主要原因是mongodb的数据flush
到磁盘。基本上每60秒(或更少)mongodb(或OS)将数据写入磁盘,并在此过程中保持global lock
。 (这有点解释随机慢查询)。在您的MMS统计信息中,请参阅background flush avg
的图表...如果它的高,则意味着您必须获得更快的磁盘。
在我们的案例中,我们移至EBS optimized
中的新EC2
个实例,并将我们配置的IOPS
从100
提升到500
,这几乎减半了background flush avg
现在服务器更快乐了。