MongoDB против CouchDB (оптимизация скорости)
Я сделал несколько тестов скорости для сравнения MongoDB и CouchDB. Во время тестирования были только вставки. Я получил MongoDB в 15 раз быстрее, чем CouchDB. Я знаю, что это из-за сокетов против http. Но мне очень интересно, как я могу оптимизировать вставки в CouchDB?
Платформа тестирования: Windows XP SP3 32 бит.
Я использовал последние версии MongoDB, MongoDB С# Driver и последнюю версию установочный пакет для CouchDB для Windows.
Спасибо!
Ответы
Ответ 1
Для вставки большого количества данных в БД массовым способом CouchDB поддерживает объемные вставки, которые описаны в wiki под HTTP Bulk Document API.
Кроме того, проверьте конфигурацию delayed_commits
и опцию batch=ok
, описанную в приведенной выше ссылке. Эти опции позволяют аналогичное поведение кэширования памяти с периодической синхронизацией с ним.
Ответ 2
Просто для повторения в сокетах vs HTTP и fsync vs in-memory.
По умолчанию MongoDB не возвращает ответ на вызов записи. Вы просто записываете свои данные в сокет и принимаете его в БД и доступны. При одновременной нагрузке это может получить резервную копию, и нет хорошего способа узнать, насколько быстро наступает Mongo, если вы не используете дополнительный вызов, который будет возвращать ответ для записи, как только данные будут доступны.
Я не говорю, что производительность Mongo вставки не быстрее, чем у Couch, вставка в память намного быстрее, чем fsyncing на диск, тем больше разница в различиях в задачах MongoDB и CouchDB о согласованности и долговечности. Но все инструменты "производительности", которые я видел для тестирования Mongo, используют API записи по умолчанию, поэтому вы не проверяете производительность вставки, которую вы тестируете, как быстро вы можете скрыться в сокете.
Я видел много тестов, которые показывают Mongo быстрее, чем Redis и memcached, потому что они не понимают, что Redis и Memcached возвращают ответ, когда данные хранятся в памяти, а Mongo - нет. Mongo определенно не быстрее, чем Redis:)
Ответ 3
Я не думаю, что разница между сокетами и http - единственная разница. Разница также связана с синхронизацией диска (fsync). Это влияет на долговечность. MongoDB сначала хранит все в ОЗУ, и он только синхронизируется с диском через определенные промежутки времени, если вы явно не указали MongoDB на выполнение fsync.
Прочитайте о долговечности и MongoDB: http://blog.mongodb.org/post/381927266/what-about-durability и fsync: http://www.mongodb.org/display/DOCS/fsync+Command
Ответ 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
, как в документация объемных документов CouchDB.
Оптимизация вторичной объемной вставки
Однако вторая оптимизация заключается в предварительной загрузке журналов в один более крупный документ Couch. Например, партиями 4 (в реальном мире это будет намного выше):
{ "_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"},
]
}
Конечно, вы также вставляете их через _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
или любыми другими вашими потребностями.
Заключение
Это все еще не сравнивается с базой данных, но я надеюсь, что для некоторых видов данных пакетная обработка в clumps уменьшит внутреннюю запись B-дерева. В сочетании с _bulk_docs
, я надеюсь, что пропускная способность вставки попадет в аппаратные скорости диска.