Подтвердить что ты не робот

Сравнение производительности MongoDB и RethinkDB Bulk Insert

Это мой официальный первый вопрос здесь; Я приветствую любую критику моего поста, чтобы я мог узнать, как стать лучшим гражданином СО.

Я проверяю нереляционные СУБД для хранения потенциально больших списков отказа электронной почты, опираясь на MongoDB или RethinkDB, используя их соответствующие клиентские библиотеки Python. Болевой точкой моего приложения является объемная производительность вставки, поэтому я установил два сценария Python для вставки 20 000 записей в партиях по 5000 в оба файла MongoDB и RethinkDB.

Пиктограмма MongoDB script mongo_insert_test.py:

NUM_LINES = 20000
BATCH_SIZE = 5000

def insert_records():
    collection = mongo.recips
    i = 0
    batch_counter = 0
    batch = []
    while i <= NUM_LINES:
        i += 1
        recip = {
            'address': "test%[email protected]%d.com" % (i, i)
        }
        if batch_counter <= BATCH_SIZE:
            batch.append(recip)
            batch_counter += 1
        if (batch_counter == BATCH_SIZE) or i == NUM_LINES:
            collection.insert(batch)
            batch_counter = 0
            batch = []

if __name__ == '__main__':
    insert_records()

Почти идентичный python RethinkDB script rethink_insert_test.py:

NUM_LINES = 20000
BATCH_SIZE = 5000

def insert_records():
    i = 0
    batch_counter = 0
    batch = []
    while i <= NUM_LINES:
        i += 1
        recip = {
            'address': "test%[email protected]%d.com" % (i, i)
        }
        if batch_counter <= BATCH_SIZE:
            batch.append(recip)
            batch_counter += 1
        if (batch_counter == BATCH_SIZE) or i == NUM_LINES:
            r.table('recip').insert(batch).run()
            batch_counter = 0
            batch = []

if __name__ == '__main__':
    insert_records()

В моей среде dev, MongoDB script вставляет за 20 000 записей:

$ time python mongo_insert_test.py 
real    0m0.618s
user    0m0.400s
sys     0m0.032s

В той же среде RethinkDB script выполняет гораздо медленнее, вставляя 20 000 записей за 2 минуты:

$ time python rethink_insert_test.py
real    2m2.502s
user    0m3.000s
sys     0m0.052s

Мне не хватает чего-то огромного здесь в отношении того, как работают эти две СУБД? Почему RethinkDB так плохо справляется с этим тестом?

У моей машины Dev было около 1,2 ГБ доступной памяти для этих тестов.

4b9b3361

Ответ 1

RethinkDB в настоящее время реализует пакетные вставки, делая одну вставку одновременно на сервере. Поскольку Rethink сбрасывает каждую запись на диск (потому что он сначала учитывает безопасность), это очень плохо влияет на рабочие нагрузки, подобные этой.

Мы делаем две вещи, чтобы решить эту проблему:

  • Массовые вставки будут реализованы с помощью алгоритма объемной вставки на сервере, чтобы избежать выполнения одной вставки за раз.
  • Мы предоставим вам возможность уменьшить ограничения долговечности, чтобы позволить кэш-памяти поглощать высокопроизводительные вставки, если вы хотите (в обмен на не синхронизацию с диском так часто).

Это будет абсолютно исправлено через 4-12 недель (и если вам нужно это как можно скорее, не стесняйтесь снимать мне электронное письмо на [email protected], и я посмотрю, можем ли мы переориентировать).

Вот соответствующие проблемы github:

https://github.com/rethinkdb/rethinkdb/issues/207

https://github.com/rethinkdb/rethinkdb/issues/314

Надеюсь, это поможет. Пожалуйста, не стесняйтесь пинговать нас, если вам нужна помощь.

Ответ 2

Оставляя в стороне то, что написал coffemug:

  • в зависимости от того, какую версию драйвера вы используете и как вы настраиваете соединение с mongodb, эти вставки могут даже не быть подтверждены сервером. Если вы используете последнюю версию драйвера Python, эти операции ждут только для подтверждения квитанции с сервера (что не означает, что данные были записаны даже в память). Для получения более подробной информации о том, что я имею в виду, обратитесь к настройке проблемы Mongodb

  • вы могли бы ускорить работу в случае Rethinkdb, распараллеливая вставки. В принципе, если вы будете запускать несколько процессов/потоков, вы увидите, что скорость растет. В случае Mongo, из-за блокировок, parallelism не поможет.

При этом RethinkDB может улучшить скорость записи.

PS: Я работаю над Rethink, но вышеупомянутые моменты основаны на моем непредвзятом знании обеих систем.

Ответ 3

Разработчик Pymongo здесь - на всякий случай, если вы этого не сделаете, убедитесь, что вы используете последнюю версию pymongo и MongoClient или MongoRepicaSetClient, чтобы ваши записи были подтверждены, а не стреляли и не забывали. Как говорит @Alex, они, скорее всего, будут тем, что вам нужно.

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

Ответ 4

Прошу простить аналогию, но это делает мою точку кристально чистой.

Не нужно много времени, чтобы зафиксировать что-то ценное в сейфе, но делать это в тысячи раз. Если вы отправили в банковское хранилище вместо этого, подумайте о том, что ваше ценное время не является безопасным во время его поездки в ваш банк; эта посылка, вероятно, будет сложена множеством других посылок - от единомышленников-вкладчиков. Кто-то обойдется, чтобы открыть вашу посылку, а затем свалить ее другими вещами, которые будут помещены в безопасное хранилище.

В этом разница между регулярными фиксациями данных на диске и пакетированием или ленивой записью данных на диск. Это компромисс между более высокой целостностью данных и улучшенной производительностью записи. Если потеря данных не имеет большого значения, то вполне приемлемо синхронизировать с диском реже, периодически или лениво записывать обновления. Неправильный выбор укусит вас в задницу в один прекрасный день, поэтому выбирайте разумно!