我做了一些速度测试来比较MongoDB和CouchDB。测试时仅插入。我使MongoDB比CouchDB快15倍。我知道这是因为套接字vs http。但是,对我来说非常有趣的是如何在CouchDB中优化插入?
测试平台:Windows XP SP3 32位。 我使用了最新版本的MongoDB,MongoDB C#驱动程序和CouchDB for Windows的installation package的最新版本。
谢谢!
答案 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}},我希望看到插入吞吐量达到磁盘的硬件速度。