对使用mongo作为数据库的设置进行负载测试时,我注意到mongo经常记录这种类型的消息都属于同一个操作:
Thu May 16 20:44:20.101 [conn3] command voterdb.$cmd command: { group: { ns: "vote",
$reduce: function ( curr, result ) { result.count++; }, cond: { p: "59a0f4cd-8c0c-49c4-
8a11-0e1ac6d89c4a" }, initial: { count: 0 }, out: "inline", key: { p: 1, q: 1, a: 1 } }
} ntoreturn:1 keyUpdates:0 numYields: 2 locks(micros) r:228316 reslen:876 136ms
应用程序很简单,我将文档添加到集合中,并且每添加一个文档,我需要更新每种类型的数据。因此,执行分组操作,其中此集合中的文档按类型分组。
我注意到,当测试结束时,mongo会继续显示这些消息,并在测试结束几分钟后处理这些分组查询(意味着查询正在延迟处理)。
我读到mongo是作家贪婪的,我也读过关于屈服的操作。我是否正确地假设插入优先于分组并且正在产生分组操作导致测试后处理?
答案 0 :(得分:3)
MongoDB在DB上使用读取器和写入器锁,这意味着编写器在DB上拥有独占锁,而多个读取器可以共享锁。为了防止长时间运行的操作阻止编写器和读取器队列,MongoDB支持让步。主要方法是在存储器操作中首先快速提供服务而不必等待进入磁盘的操作。下面是一个链接,提供有关屈服和分析统计数据的更多细节。
http://docs.mongodb.org/manual/faq/concurrency/#faq-concurrency-yielding http://docs.mongodb.org/manual/reference/database-profiler/
还有一些关于应用程序描述的想法。我必须详细介绍最佳方法,但我觉得你的设计效率更高。
使用聚合框架与地图缩减:看起来您可能正在使用MR流程来执行计数。聚合框架的开销明显减少,而且几乎总是更快。
如果事实证明你正在进行计数,看看你是否可以简单地执行db.collection.find({..})。count(),因为这将非常快。计数缓存在索引中。
最后,您是否需要对插入的每个文档执行聚合?有各种选择。例如,您只想增加($ inc)某个计数器,或者在后台定期执行聚合。完美的情况是,以一种类型的粒度存储文档是可行的,这将允许您同时执行计数和插入操作。