Наскільки швидше Redis, ніж mongoDB?


204

Широко згадується, що Redis є "Blazing Fast", і mongoDB також швидко. Але у мене виникають проблеми з пошуку фактичних цифр, порівнюючи результати цих двох. З огляду на подібні конфігурації, функції та операції (а може бути показано, як змінюється коефіцієнт у різних конфігураціях та операціях) тощо, чи Redis на 10 разів швидший ?, 2x швидше ?, 5x швидше?

Я ТОЛЬКО кажу про виконання. Я розумію, що mongoDB - це інший інструмент і має більш багатий набір функцій. Це не дебати "Чи краще mongoDB, ніж Redis". Я запитую, за якою маржею Redis перевершує mongoDB?

На сьогоднішній день навіть дешеві орієнтири є кращими, ніж відсутні показники.


10
Дешеві орієнтири завжди кращі, ніж відсутні показники. Дякую за товариша за питання.
Мазіяр

2
Взагалі, турбота про різницю між 5000 оп / с і 10 000 оп / с часто є випадком передчасної оптимізації. Це сказав, що це все ще цікава відповідь :)
Кевін,

Відповіді:


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 та найновіші пімонго / 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

Отримайте результати звичайно із зерном солі! Якщо ви програмуєте іншою мовою, використовуючи інших клієнтів / різні реалізації тощо, ваші результати будуть різними. Не кажучи вже про ваше використання буде зовсім іншим! Ваша найкраща ставка - орієнтувати їх самостійно, саме таким чином, яким ви їх збираєтесь використовувати. Як наслідок, ви, мабуть, з’ясуєте найкращий спосіб їх використання. Завжди орієнтир для себе!


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 сервери. Це означає, що ваші записи не чекають синхронізації диска, а реплікації мережі перед поверненням. Не чекати помилок - це щось, що ніколи не робилося на продажі. як не виявлення, чи підключений мережевий кабель під час запису до мережі.
sivann

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 не працює. Монго сповільнюватиметься в кількості, що залежить від типу навантаження. Що стосується лише типу вставки, один користувач нещодавно повідомив про уповільнення величини від 6 до 7 порядків (від 10 000 до 100 000 разів), але цей звіт також визнав, що виникли проблеми з конфігурацією, і що це було дуже нетиповим робочим навантаженням. Нормальне зчитування великого навантаження анекдотично повільно приблизно в 10 разів, коли деякі дані потрібно зчитувати з диска.

Висновок: Redis буде швидше, але не на всю партію.


7

Ось чудова стаття про ефективність сеансу в рамках Торнадо близько 1 року. Він має порівняння між декількома різними реалізаціями, серед яких Redis та MongoDB включені. У графіку статті зазначено, що Redis відстає від MongoDB приблизно на 10% у цьому конкретному випадку використання.

Redis має вбудований тест, який буде аналізувати продуктивність машини, на якій ви працюєте. У вікі Бенчмарк для Redis є тонна нераціональних даних. Але вам, можливо, доведеться трохи озирнутися навколо Монго. Як тут , тут , і деякі випадкові числа полірувати (але це дає вам відправну точку для запуску деякого MongoDB контрольних показників себе).

Я вважаю, що найкращим рішенням цієї проблеми є тестування самостійно в тих ситуаціях, які ви очікуєте.


Базові показники Tornado добре узгоджуються з моїми власними тестами щодо використання Redis та MongoDb як резервного копіювання Zend_Cache. Багатіша функціональність MongoDb дозволяє використовувати менше запитів та багатопотокові масштаби дизайну набагато краще, ніж один процес Redis, який не є багатопоточним. Висновок полягає в тому, що масштаби MongoDb вище. Також Redis більше не підтримує віртуальну пам'ять.
ColinM

3

У моєму випадку визначальним фактором порівняння продуктивності є те, що використовується MongoDb WriteConcern. Більшість драйверів монго нині встановить параметр WriteConcern за замовчуванням ACKNOWLEDGED, що означає «записано в оперативну пам’ять» ( Mongo2.6.3-WriteConcern ), в цьому відношенні це було дуже порівнянно з Redis для більшості операцій запису.

Але реальність залежить від ваших потреб програми та налаштування виробничого середовища, ви можете змінити цю проблему на WriteConcern.JOURNALED (написано в оплогу) або WriteConcern.FSYNCED (записано на диск) або навіть записано набори реплік (резервні копії) якщо це потрібно.

Тоді ви можете почати спостерігати деяке зниження продуктивності. Інші важливі фактори також включають, наскільки оптимізовані ваші схеми доступу до даних, пропуск індексу% (див. Монгостат ) та індекси загалом.


0

Я думаю, що 2-3X на показаному орієнтирі вводять в оману, оскільки якщо ви це також залежить від обладнання, на якому ви працюєте, - з мого досвіду, чим сильніше машина, тим більший розрив (на користь Redis) буде, мабуть, тим, що тест досить швидко досяг межі межі пам'яті.

Що стосується ємності пам'яті - це частково відповідає дійсності, оскільки існують також способи подолати це, є (комерційні) продукти, які записують дані Redis на диск, а також кластерні (багатошарові) рішення, що долають розмір пам'яті обмеження.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.