我正在为一个Web应用程序运行写密集型MongoDB,而且我的性能非常差。话虽如此,我相当肯定这个问题与我们的代码,设置和/或我们的用法有关,而不是mongo本身。
我打算用绝望的大锤打开我的头,所以我想知道是否有人会介意看看我准备好的一些输出,看看是否有任何问题。
代码不是太复杂(它在PHP中,顺便说一句)。它几乎是 - > find()和 - > update()。我确保为这两个调用使用索引,并确认它们确实是通过对查询执行explain()来使用的。
我已经尝试过1台服务器(ec2 m2.2xlarge),4台服务器(2台服务器的2个分片)和9台服务器(3个服务器的3个分片)并且无法从这些服务器中获得更多。
好时刻,我无法获得超过每秒1500次写入的内容(插入+更新)。大多数时候,我很幸运能够达到100次插入/更新的总和,并且我总是有一个很大的“锁定%”并且很多查询排队等待“qr | qw”。
现在,我有一个正在运行且正在爬行的脚本。最糟糕的是,当我查看mongostat一段时间时,“res”中使用的RAM量大约是服务器可用RAM的50%,并且有足够的RAM来容纳所有集合的索引。没有理由为什么这不会像疯了一样吐出数据。
我必须已经将应用程序重新编码2-3次,试图找到更好的数据访问模式。我已经读过关于索引,更新,分片键以及什么不能读取的所有内容。我放入mongo的所有服务器都使用了8个EBS磁盘raid 10设置并添加了一些性能调整(blockdev,noatime等等)。
我知道问题出在我的最后,我不是在责备mongodb。我知道比我更大的公司正在将它用于密集型应用程序并且他们非常喜欢它(例如foursquare)。与此同时,我无法理解我做错了什么以及为什么我的表现如此糟糕,无论我做什么。
其他信息:
答案 0 :(得分:10)
所以第一个问题是你的磁盘似乎主要是阅读而不是写作。 (基于iostat
)。你的利用率已超过50%,但基本上都是读数。
如果我查看您的数据库统计信息,您在133GB的已分配文件中有35GB的索引和41GB的数据。 133GB与mapped
中的mongostat
号码非常接近。因此,您可能访问的数据总和约为120GB或大约4倍RAM。
通常4倍是完美的比例。但是,在您的情况下,您的索引超过RAM。这往往是MongoDB中性能的“衰减”点。
如果您在索引中随机访问,则大部分或全部索引都在内存中。这意味着您的大多数数据都不在内存中,需要从磁盘“分页”。你可以在重磅磁盘读取中看到这一点。
我知道你说你用分片测试过,你有测试的数字吗?数据是否正确分布在所有三个分片中?
当您向数据库“添加更多RAM”时,分片应该可以缓解您的问题,但您需要确认数据确实是均匀分片并且行为正确或无法解决您的问题。