MongoDB与CouchDB(速度优化)

时间:2010-06-02 04:10:34

标签: windows performance testing mongodb couchdb

我做了一些速度测试来比较MongoDB和CouchDB。测试时仅插入。我使MongoDB比CouchDB快15倍。我知道这是因为套接字vs http。但是,对我来说非常有趣的是如何在CouchDB中优化插入?

测试平台:Windows XP SP3 32位。 我使用了最新版本的MongoDB,MongoDB C#驱动程序和CouchDB for Windows的installation package的最新版本。

谢谢!

4 个答案:

答案 0 :(得分:26)

只需迭代套接字vs HTTP和fsync vs内存中对话。

默认情况下,MongoDB不会在写入调用时返回响应。您只需将数据写入套接字并假设它在数据库中并且可用。在并发加载下,这可能会被备份,并且没有一种好方法可以知道Mongo 真正的速度有多快,除非你使用一个可选的调用,一旦数据可用就会返回写入的响应。

我不是说Mongo插入性能不比Couch快,插入内存比fsyncing到光盘要快得多,这里更大的区别在于MongoDB和CouchDB在一致性和持久性方面的目标差异。但是我见过的用于测试Mongo的所有“性能”工具都使用默认的写入API,因此您并没有真正测试插入性能,而是测试了刷新插槽的速度。

我已经看到很多基准测试显示Mongo比Redis和memcached更快,因为他们没有意识到Redis和Memcached在数据在内存中时返回响应而Mongo没有。 Mongo肯定不比更快<:>

答案 1 :(得分:11)

为了以批量方式将大量数据插入到数据库中,CouchDB支持批量插入,这些内容在HTTP Bulk Document API下的wiki中进行了描述。

此外,请查看delayed_commits配置选项以及上述链接中描述的batch=ok选项。这些选项启用类似的内存缓存行为,并对磁盘进行定期同步。

答案 2 :(得分:5)

我不认为套接字和http之间的区别是唯一的区别。差异还与磁盘同步(fsync)有关。这会影响耐久性。 MongoDB首先将所有内容存储在RAM中,它只会以特定间隔同步到磁盘,除非您明确告诉MongoDB执行fsync。

了解耐久性和MongoDB:http://blog.mongodb.org/post/381927266/what-about-durability和fsync:http://www.mongodb.org/display/DOCS/fsync+Command

答案 3 :(得分:4)

这是我一直在考虑但未进行基准测试的想法。我希望它在某些情况下很棒:

  • 插入吞吐量必须很高
  • 不需要按密钥提取单个文档
  • 所有数据都是通过视图获取的(可能是与接收插件的机器不同的机器)

计划

插入批量文档,并使用视图将它们序列化很好。

实施例

考虑一个带有简单时间戳和消息字符串的日志文件。

0.001 Start
0.123 This could be any message
0.500 Half a second later!
1.000 One second has gone by
2.000 Two seconds has gone by
[...]
1000.000 One thousand seconds has gone by

您可以在每个文档中插入一条消息,例如:

{ "_id": "f30d09ef6a9e405994f13a38a44ee4a1",
  "_rev": "1-764efa883dda1e11db47671c4a3bbd9e",
  "timestamp": 0.123,
  "message": "This could be any message"
}

标准批量文档优化

第一个优化是使用_bulk_docs中的{ "_id": "f30d09ef6a9e405994f13a38a44ee4a1", "_rev": "1-764efa883dda1e11db47671c4a3bbd9e", "logs": [ {"timestamp": 0.001, "message": "Start"}, {"timestamp": 0.123, "message": "This could be any message"}, {"timestamp": 0.500, "message": "Half a second later!"}, {"timestamp": 1.000, "message": "One second has gone by"} ] } { "_id": "74f615379d98d3c3d4b3f3d4ddce82f8", "_rev": "1-ea4f43014d555add711ea006efe782da", "logs": [ {"timestamp": 2.000, "message": "Two seconds has gone by"}, {"timestamp": 3.000, "message": "Three seconds has gone by"}, {"timestamp": 4.000, "message": "Four seconds has gone by"}, {"timestamp": 5.000, "message": "Five seconds has gone by"}, ] } 进行插入。

辅助批量插入优化

但是,第二次优化是将日志预先批处理为一个较大的Couch文档。例如,批量为4(在现实世界中,这将高得多):

_bulk_docs

当然,您也可以通过// map function(doc) { if(doc.logs) { // Just unroll the log batches! for (var i in doc.logs) { var log = doc.logs[i]; emit(log.timestamp, log.message); } } } 插入这些内容,有效地插入批量数据

视图仍然很容易

将日志序列化回视图仍然非常容易:

startkey

然后很容易获取时间戳介于endkey_bulk_docs或其他任何其他需求之间的日志。

结论

这仍然没有基准测试,但我希望,对于某些类型的数据,批处理成块将减少内部B树写入。结合{{1}},我希望看到插入吞吐量达到磁盘的硬件速度。