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

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

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

скрипт MongoDB python 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%d@test%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()

почти идентичный скрипт RethinkDB python 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%d@test%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()

в моей среде разработки скрипт MongoDB вставляет 20 000 записей за секунду:

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

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

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

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

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

4 ответов


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

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

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

Это совершенно будет исправлено в 4-12 неделях (и если вам нужно это как можно скорее, то чувствуйте свободным снять меня электронная почта к slava@rethinkdb.com и я посмотрю, сможем ли мы изменить приоритет).

вот соответствующие github вопросы:

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

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

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


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

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

  2. вы можете получить скорость в случае Rethinkdb путем распараллеливания вставок. В основном, если вы запустите несколько процессов / потоков, вы увидите, что скорость растет. В случае Монго, из-за задействованных замков, параллелизм не поможет.

Это, как говорится, RethinkDB может улучшить скорость записи.

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


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

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


пожалуйста, простите аналогию-однако это делает мою точку зрения кристально ясной.

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

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