MongoDB против CouchDB (оптимизация скорости) - PullRequest
13 голосов
/ 02 июня 2010

Я сделал несколько тестов скорости, чтобы сравнить MongoDB и CouchDB. Только вкладыши были при тестировании. Я получил MongoDB в 15 раз быстрее, чем CouchDB. Я знаю, что это из-за сокетов против http. Но мне очень интересно, как я могу оптимизировать вставки в CouchDB?

Тестовая платформа: Windows XP SP3 32 бит. Я использовал последние версии MongoDB, драйвер MongoDB C # и последнюю версию установочного пакета CouchDB для Windows.

Спасибо!

Ответы [ 4 ]

26 голосов
/ 03 июня 2010

Просто для перебора сокетов против HTTP и fsync против диалога в памяти.

По умолчанию MongoDB не возвращает ответ на вызов записи. Вы просто записываете свои данные в сокет и предполагаете, что они находятся в БД и доступны. При одновременной загрузке это может быть сохранено, и нет хорошего способа узнать, насколько быстрым является Mongo на самом деле , если только вы не используете дополнительный вызов, который вернет ответ для записи, как только данные станут доступны.

Я не говорю, что производительность вставки Mongo не выше, чем Couch, вставка в память намного быстрее, чем fsyncing на диск, большая разница здесь в разнице в целях, которые MongoDB и CouchDB имеют в отношении согласованности и долговечности. Но все инструменты «производительности», которые я видел для тестирования Mongo, используют API записи по умолчанию, поэтому вы на самом деле не тестируете производительность вставки, вы проверяете, насколько быстро вы можете выполнить сброс в сокет.

Я видел множество тестов, которые показывают, что Mongo работает быстрее, чем Redis и memcached, потому что они не понимают, что Redis и Memcached возвращают ответ, когда данные находятся в памяти, а Mongo - нет. Mongo определенно не быстрее, чем Redis:)

11 голосов
/ 03 июня 2010

Для массовой загрузки данных в БД CouchDB поддерживает массовые вставки , которые описаны в вики в разделе HTTP Bulk Document API .

Кроме того, проверьте параметр конфигурации delayed_commits и параметр batch=ok, описанные в приведенной выше ссылке. Эти параметры обеспечивают аналогичное поведение при кэшировании памяти с периодической синхронизацией с диском.

5 голосов
/ 02 июня 2010

Не думаю, что разница между сокетами и 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 голосов
/ 03 июня 2010

Вот идея, о которой я думал, но не тестировал. Я ожидаю, что это будет хорошо в определенных ситуациях:

  • Пропускная способность вставки должна быть высокой
  • Получение отдельных документов по ключу не требуется
  • Все данные выбираются с помощью представлений (возможно, машина отличается от той, которая получает вставки)

План

Вставка пакетов документов и использование представлений для правильной их сериализации.

Пример

Рассмотрим файл журнала с простой отметкой времени и строкой сообщения.

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

Вы можете вставить журналы по одному сообщению на документ, например ::1010 *

{ "_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 или любыми другими вашими потребностями.

Заключение

Это все еще не тестируется, но я надеюсь, что для некоторых типов данных пакетирование в комки уменьшит количество внутренних записей B-дерева. Надеюсь, что в сочетании с _bulk_docs пропускная способность вставки снизится до аппаратной скорости диска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...