Насколько быстрее Redis, чем mongoDB?

204

Широко упоминается, что Redis "Blazing Fast" и mongoDB тоже быстр. Но я не могу найти реальные цифры, сравнивая результаты двух. Учитывая аналогичные конфигурации, функции и операции (и, возможно, показывая, как фактор изменяется при разных конфигурациях и операциях) и т. Д., Redis в 10 раз быстрее, в 2 раза быстрее, в 5 раз быстрее?

Я говорю только о производительности. Я понимаю, что mongoDB - это другой инструмент и имеет более богатый набор функций. Это не дебаты "Является ли mongoDB лучше, чем Redis". Я спрашиваю, с какой разницей Redis превосходит mongoDB?

На этом этапе даже дешевые тесты лучше, чем отсутствие тестов.

Homer6
источник
10
Дешевые тесты всегда лучше, чем отсутствие тестов. Спасибо за вопрос, приятель.
Мазияр
2
В общем, забота о разнице между 5000 операций в секунду и 10000 операций в секунду часто является случаем преждевременной оптимизации. Тем не менее, это все еще интересный ответ :)
Кевин

Ответы:

238

Грубые результаты из следующего теста: 2x запись, 3x чтение .

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

#!/usr/bin/env python2.7
import sys, time
from pymongo import Connection
import redis

# connect to redis & mongodb
redis = redis.Redis()
mongo = Connection().test
collection = mongo['test']
collection.ensure_index('key', unique=True)

def mongo_set(data):
    for k, v in data.iteritems():
        collection.insert({'key': k, 'value': v})

def mongo_get(data):
    for k in data.iterkeys():
        val = collection.find_one({'key': k}, fields=('value',)).get('value')

def redis_set(data):
    for k, v in data.iteritems():
        redis.set(k, v)

def redis_get(data):
    for k in data.iterkeys():
        val = redis.get(k)

def do_tests(num, tests):
    # setup dict with key/values to retrieve
    data = {'key' + str(i): 'val' + str(i)*100 for i in range(num)}
    # run tests
    for test in tests:
        start = time.time()
        test(data)
        elapsed = time.time() - start
        print "Completed %s: %d ops in %.2f seconds : %.1f ops/sec" % (test.__name__, num, elapsed, num / elapsed)

if __name__ == '__main__':
    num = 1000 if len(sys.argv) == 1 else int(sys.argv[1])
    tests = [mongo_set, mongo_get, redis_set, redis_get] # order of tests is significant here!
    do_tests(num, tests)

Результаты для mongodb 1.8.1 и redis 2.2.5 и последней версии pymongo / redis-py:

$ ./cache_benchmark.py 10000
Completed mongo_set: 10000 ops in 1.40 seconds : 7167.6 ops/sec
Completed mongo_get: 10000 ops in 2.38 seconds : 4206.2 ops/sec
Completed redis_set: 10000 ops in 0.78 seconds : 12752.6 ops/sec
Completed redis_get: 10000 ops in 0.89 seconds : 11277.0 ops/sec

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

zeekay
источник
3
Стоит отметить, что MongoDB и Redis имеют разные структуры персистентности и что Redis поддерживает только схему данных, которая может помещаться в памяти. Хотя оперативная память обходится дешево, если вам нужно использовать / хранить более 12-16 ГБ данных, я бы посмотрел, как выглядят параметры вашего сервера.
Tracker1
53
@sivann этот пост переходит от отсутствия тестов к четко сформулированному «грубому» тесту. Не будь троллем с бредом "эталоны вводят в заблуждение". Конечно, разные условия могут изменить результаты. Внесите свой вклад и отправьте свои собственные тесты, которые проверят ваш случай и ссылку из этого поста, тогда мы все выиграем от вашего "проверенного" мнения.
Homer6
2
@sivann Конфигурация по умолчанию (поставляется) - это то, что тестировал этот тест. IMHO, конфигурация по умолчанию определяет, на какой стороне fsync находится пакет. Для Redis он объявлен сервером памяти, который призывает людей использовать другие альтернативы, когда база данных больше, чем общая системная память. Для MongoDB он рекламируется как база данных. Postgres никогда не отключит fsync, потому что они явно находятся в лагере постоянства. Большинство людей не изменяют конфигурации, поэтому этот тест достаточно точен для этих случаев.
Homer6
4
Я согласен с @sivann, тест, который вы опубликовали, имеет серьезные недостатки. MongoDB является многопоточным, а Redis - нет. Если бы ваш тест был многопоточным, вы бы увидели, что MongoDb на самом деле имеет более высокую пропускную способность на многоядерном компьютере.
ColinM
2
@ Homer6 даже для БД, ориентированной на память, вы должны тестировать с включенным WriteConcern (по умолчанию отключено). Тестирование без всякой ерунды для любого теста. Похоже на Reddis. БД, которые не синхронизируют на диске все транзакции, обеспечивают безопасность, реплицируя данные как минимум на 2 сервера. Это означает, что ваши записи ждут не синхронизации диска, а сетевой репликации перед возвратом. Не ждать ошибок - это то, что никогда не делается на продукт. вроде не обнаруживает, подключен ли сетевой кабель при записи в сеть.
Сиванн
18

Пожалуйста, проверьте этот пост об анализе эффективности вставки Redis и MongoDB:

До 5000 записей mongodb $ push быстрее даже по сравнению с Redis RPUSH, затем он становится невероятно медленным, вероятно, тип массива mongodb имеет линейное время вставки, и поэтому он становится медленнее и медленнее. mongodb может получить немного производительности, предоставляя тип списка вставки с постоянным временем, но даже с типом массива с линейным временем (который может гарантировать поиск с постоянным временем), он имеет свои приложения для небольших наборов данных.

Андрей Андрушкевич
источник
15

Хороший и простой тест

Я попытался пересчитать результаты снова, используя текущие версии redis (2.6.16) и mongo (2.4.8), и вот результат

Completed mongo_set: 100000 ops in 5.23 seconds : 19134.6 ops/sec
Completed mongo_get: 100000 ops in 36.98 seconds : 2703.9 ops/sec
Completed redis_set: 100000 ops in 6.50 seconds : 15389.4 ops/sec
Completed redis_get: 100000 ops in 5.59 seconds : 17896.3 ops/sec

Также в этом блоге сравниваются оба из них, но используется node.js. Он показывает эффект увеличения количества записей в базе данных вместе со временем.

Тарек Салах
источник
8

Числа будет трудно найти, так как они не совсем в одном месте. Общий ответ заключается в том, что Redis на 10 - 30% быстрее, когда набор данных помещается в рабочую память одного компьютера. Как только этот объем данных превышен, Redis завершается ошибкой. Mongo будет замедляться на величину, которая зависит от типа нагрузки. Для типа нагрузки «только для вставки» один пользователь недавно сообщил о замедлении на 6–7 порядков (от 10 000 до 100 000 раз), но в этом отчете также признавалось, что имелись проблемы с конфигурацией и что это была очень нетипичная рабочая нагрузка. Нормальное чтение тяжелых нагрузок анекдотически медленно примерно в 10 раз, когда некоторые данные должны быть прочитаны с диска.

Вывод: Redis будет быстрее, но не намного.

Джон Ф. Миллер
источник
7

Вот отличная статья о производительности сессий в рамках Tornado около 1 года. Он сравнивает несколько разных реализаций, среди которых Redis и MongoDB. График в статье показывает, что Redis отстает от MongoDB примерно на 10% в этом конкретном случае использования.

Redis поставляется со встроенным тестом, который будет анализировать производительность машины, на которой вы находитесь. В вики Benchmark для Redis есть тонна необработанных данных . Но вам, возможно, придется немного осмотреться в поисках Монго. Как здесь , здесь , и некоторые случайные числа для полировки (но это дает вам отправную точку для запуска некоторых тестов MongoDB самостоятельно).

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

mistagrooves
источник
Тесты Tornado хорошо согласуются с моими собственными тестами по использованию Redis и MongoDb в качестве бэкэнда Zend_Cache. Более широкие функциональные возможности MongoDb позволяют использовать меньше запросов, а многопоточный дизайн масштабируется намного лучше, чем один процесс Redis, который не является многопоточным. Вывод: MongoDb масштабируется выше. Также Redis больше не поддерживает виртуальную память.
ColinM
3

В моем случае определяющим фактором при сравнении производительности является MongoDb WriteConcern, который используется. Большинство драйверов mongo в настоящее время устанавливают для WriteConcern по умолчанию значение ACKNOWLEDGED, что означает « запись в ОЗУ» ( Mongo2.6.3-WriteConcern ), в этом отношении он был очень сопоставим с redis для большинства операций записи.

Но реальность зависит от потребностей вашего приложения и настроек производственной среды, вы можете изменить это значение на WriteConcern.JOURNALED (записано в oplog) или WriteConcern.FSYNCED (записано на диск) или даже записано в наборы реплик (резервные копии). если необходимо.

Тогда вы можете начать видеть некоторое снижение производительности. Другие важные факторы также включают, насколько оптимизированы ваши шаблоны доступа к данным, индекс пропуска% (см. Mongostat ) и индексы в целом.

чёрное
источник
0

Я думаю, что 2-3X на показанном тесте вводят в заблуждение, поскольку, если вы также зависите от аппаратного обеспечения, на котором вы его используете - по моему опыту, чем «сильнее» машина, тем больше разрыв (в пользу Redis) будет, вероятно, из-за того, что бенчмарк достигнет предела памяти довольно быстро.

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

Элиор Малул
источник