我有2个EC2实例,一个是mongodb服务器,另一个是python web应用程序(相同的可用区域)。 python服务器使用PyMongo连接到mongo服务器,一切正常。
问题是,当我在python中描述执行时间时,在某些调用中(少于5%),甚至需要几秒钟才能返回。我能够缩小问题范围,实际上是对mongo服务器的数据库调用的时间延迟。
我认为的两个原因是, 1. Mongo服务器缓慢/过载 2.网络延迟
所以,我尝试将mongo服务器升级到4倍更快的实例,但问题仍然存在(有些调用甚至需要3秒才能返回)我假设因为两台服务器都在EC2上,网络延迟应该不是问题...但可能是我错了。
如何确认问题是否真的是网络本身?如果是这样,解决它的最佳方法是什么?还有其他可能的原因吗?
感谢任何帮助...
谢谢,
UPATE:我提取的实体非常小(已编入索引),通常调用只需0.01-0.02秒即可完成。
更新:
根据“James Wahlin”的建议,我在我的mongo服务器上启用了性能分析并获得了一些有趣的日志,
Marri Mar 15 18:05:22 [conn88635]查询db.UserInfoShared查询:{$或: [{_locked:{$ exists:false}},{_ locked:{$ lte: 1363370603.297361}}],_ id:“750837091142”} nto返回:1 nscanned:1 nreturned:1 reslen:47 2614ms
Marri Mar 15 18:05:22 [conn88635]命令db。$ cmd命令:{ findAndModify:“UserInfoShared”,字段:{_ id:1},upsert:true, 查询:{$或:[{_locked:{$ exists:false}},{_ locked:{$ lte: 1363370603.297361}}],_ id:“750837091142”},更新:{$ set:{_locked:1363370623.297361}},new:true} ntoreturn:1 reslen:153 2614ms
你可以看到这两个电话完成时间超过2秒。字段_id
是唯一索引的,发现它不应该花费这么多时间。可能是我必须为它发布一个新问题,但mongodb GLOBAL LOCK可以成为原因吗?
答案 0 :(得分:2)
@James Wahlin,非常感谢你帮助我。
事实证明,延迟的主要原因是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
现在服务器更快乐了。