Wie viel schneller ist Redis als mongoDB?

204

Es ist weit verbreitet, dass Redis "Blazing Fast" ist und mongoDB auch schnell ist. Aber ich habe Probleme, tatsächliche Zahlen zu finden, die die Ergebnisse der beiden vergleichen. Ist Redis bei ähnlichen Konfigurationen, Funktionen und Vorgängen (und zeigt möglicherweise, wie sich der Faktor bei unterschiedlichen Konfigurationen und Vorgängen ändert) usw. 10x schneller?, 2x schneller?, 5x schneller?

Ich spreche NUR von Leistung. Ich verstehe, dass mongoDB ein anderes Tool ist und einen umfangreicheren Funktionsumfang hat. Dies ist nicht die Debatte "Ist MongoDB besser als Redis". Ich frage, um welchen Vorsprung übertrifft Redis mongoDB?

Zu diesem Zeitpunkt sind sogar billige Benchmarks besser als keine Benchmarks.

Homer6
quelle
10
Billige Benchmarks sind immer besser als keine Benchmarks. Danke für die Frage Kumpel.
Maziyar
2
Im Allgemeinen ist die Berücksichtigung des Unterschieds zwischen 5.000 Operationen / Sek. Und 10.000 Operationen / Sek. Oft ein Fall vorzeitiger Optimierung. Das heißt, es ist immer noch eine interessante Antwort :)
Kevin

Antworten:

238

Grobe Ergebnisse aus dem folgenden Benchmark: 2x Schreiben, 3x Lesen .

Hier ist ein einfacher Benchmark in Python, den Sie an Ihre Zwecke anpassen können. Ich habe mir angesehen, wie gut jeder einzelne funktioniert, wenn er einfach Werte setzt / abruft:

#!/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)

Ergebnisse für mit mongodb 1.8.1 und redis 2.2.5 und neuestem 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

Nehmen Sie die Ergebnisse natürlich mit einem Körnchen Salz! Wenn Sie in einer anderen Sprache programmieren, andere Clients / andere Implementierungen usw. verwenden, variieren Ihre Ergebnisse stark. Ganz zu schweigen davon, dass Ihre Nutzung völlig anders sein wird! Am besten vergleichen Sie sie selbst, genau so, wie Sie sie verwenden möchten. Als Konsequenz werden Sie wahrscheinlich herausfinden, wie Sie jeden einzelnen am besten nutzen können. Immer Benchmark für sich selbst!

Zeekay
quelle
3
Es ist erwähnenswert, dass MongoDB und Redis unterschiedliche Persistenzstrukturen haben und dass Redis nur ein Datenschema unterstützt, das in den Speicher passt. Obwohl RAM billig ist, würde ich sehen, wie Ihre Serveroptionen aussehen, wenn Sie mehr als 12-16 GB Daten verwenden / speichern müssen.
Tracker1
53
@sivann Dieser Beitrag geht von keinen Benchmarks zu einem klar definierten "groben" Benchmark. Sei kein Troll mit dem Unsinn "Benchmarks sind irreführend". Natürlich können unterschiedliche Bedingungen die Ergebnisse verändern. Tragen Sie zurück und reichen Sie stattdessen Ihre eigenen Benchmarks ein, die Ihren Fall testen und von diesem Beitrag verlinken. Dann profitieren wir alle von Ihrer "getesteten" Meinung.
Homer6
2
@sivann Die Standardkonfiguration (ausgeliefert) wurde von diesem Benchmark getestet. IMHO bestimmt die Standardkonfiguration, auf welcher Seite des fsync-Zauns sich ein Paket befindet. Für Redis wird es als Speicherserver beworben, der die Benutzer auffordert, andere Alternativen zu verwenden, wenn die Datenbank größer als der gesamte Systemspeicher ist. Für MongoDB wird es als Datenbank beworben. Postgres würde fsync niemals ausschalten, weil sie sich eindeutig im Persistenzlager befinden. Die meisten Benutzer ändern die Konfigurationen nicht, daher ist dieser Benchmark für diese Fälle ziemlich genau.
Homer6
4
Ich stimme @sivann zu, der von Ihnen veröffentlichte Benchmark ist fatal fehlerhaft. MongoDB ist Multithread-fähig und Redis nicht. Wenn Ihr Benchmark Multithreading wäre, würden Sie sehen, dass MongoDb auf einem Multi-Core-Computer tatsächlich einen höheren Durchsatz hat.
ColinM
2
@ Homer6 Auch für speicherorientierte DB sollten Sie mit aktiviertem WriteConcern testen (standardmäßig deaktiviert). Testen ohne ist wirklich Unsinn für jede Art von Benchmark. Ähnliches gilt für reddis. DBs, die nicht alle Transaktionen auf der Festplatte synchronisieren, gewährleisten die Sicherheit, indem sie die Daten auf mindestens 2 Server replizieren. Das bedeutet, dass Ihre Schreibvorgänge nicht auf eine Festplattensynchronisierung warten, sondern auf die Netzwerkreplikation, bevor Sie zurückkehren. Nicht auf Fehler zu warten, ist etwas, was bei Prod nie gemacht wurde. B. beim Schreiben in das Netzwerk nicht zu erkennen, ob das Netzwerkkabel angeschlossen ist.
Sivann
18

Bitte lesen Sie diesen Beitrag über die Analyse der Einfügungsleistung von Redis und MongoDB:

Bis zu 5000 Einträge mongodb $ push ist sogar im Vergleich zu Redis RPUSH schneller, dann wurde es unglaublich langsam, wahrscheinlich hat der Mongodb-Array-Typ eine lineare Einfügezeit und wird daher immer langsamer. mongodb kann ein wenig an Leistung gewinnen, wenn ein Listentyp mit konstanter Zeiteinfügung verfügbar gemacht wird, aber selbst mit dem linearen Zeitarraytyp (der eine konstante Zeitsuche gewährleisten kann) hat es seine Anwendungen für kleine Datensätze.

Andrei Andrushkevich
quelle
15

Guter und einfacher Benchmark

Ich habe versucht, die Ergebnisse mit den aktuellen Versionen von redis (2.6.16) und mongo (2.4.8) erneut zu berechnen. Hier ist das Ergebnis

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

Auch dieser Blog-Beitrag vergleicht beide, verwendet jedoch node.js. Es zeigt den Effekt einer zunehmenden Anzahl von Einträgen in der Datenbank zusammen mit der Zeit.

Tareq Salah
quelle
8

Zahlen werden schwer zu finden sein, da sich die beiden nicht ganz im selben Raum befinden. Die allgemeine Antwort lautet, dass Redis 10 - 30% schneller ist, wenn der Datensatz in den Arbeitsspeicher einer einzelnen Maschine passt. Sobald diese Datenmenge überschritten ist, schlägt Redis fehl. Mongo verlangsamt sich mit einer Menge, die von der Art der Ladung abhängt. Für einen Lasttyp nur für Einfügungen meldete ein Benutzer kürzlich eine Verlangsamung um 6 bis 7 Größenordnungen (10.000 bis 100.000 Mal), aber dieser Bericht gab auch zu, dass es Konfigurationsprobleme gab und dass dies eine sehr atypische Arbeitslast war. Normale Leselastlasten verlangsamen sich anekdotisch um das 10-fache, wenn einige der Daten von der Festplatte gelesen werden müssen.

Fazit: Redis wird schneller sein, aber nicht viel.

John F. Miller
quelle
7

Hier ist ein ausgezeichneter Artikel über die Sitzungsleistung im Tornado-Framework, der ungefähr 1 Jahr alt ist. Es gibt einen Vergleich zwischen einigen verschiedenen Implementierungen, von denen Redis und MongoDB enthalten sind. Die Grafik im Artikel zeigt, dass Redis in diesem speziellen Anwendungsfall um etwa 10% hinter MongoDB liegt.

Redis verfügt über einen integrierten Benchmark, der die Leistung der Maschine analysiert, auf der Sie sich befinden. Im Benchmark-Wiki für Redis gibt es eine Menge Rohdaten davon . Aber vielleicht müssen Sie sich ein bisschen nach Mongo umsehen. Wie hier , hier und einige zufällige polnische Zahlen (aber es gibt Ihnen einen Ausgangspunkt, um einige MongoDB-Benchmarks selbst auszuführen).

Ich glaube, die beste Lösung für dieses Problem besteht darin, die Tests in den von Ihnen erwarteten Situationen selbst durchzuführen.

Mistagrooves
quelle
Die Tornado-Benchmarks stimmen gut mit meinen eigenen Tests zur Verwendung von Redis und MongoDb als Zend_Cache-Backend überein. Dank der umfangreicheren Funktionalität von MongoDb können Sie weniger Anforderungen verwenden und das Multithread-Design lässt sich weitaus besser skalieren als ein einzelner Redis-Prozess, der kein Multithread-Prozess ist. Schlussfolgerung ist, dass MongoDb höher skaliert. Außerdem unterstützt Redis keinen virtuellen Speicher mehr.
ColinM
3

In meinem Fall war der verwendete MongoDb WriteConcern ein entscheidender Faktor für den Leistungsvergleich. Die meisten Mongo-Treiber setzen heutzutage das Standard-WriteConcern auf ACKNOWLEDGED, was "in den RAM geschrieben" bedeutet ( Mongo2.6.3-WriteConcern ). In dieser Hinsicht war es für die meisten Schreibvorgänge sehr vergleichbar mit Redis.

Die Realität hängt jedoch von Ihren Anwendungsanforderungen und dem Setup der Produktionsumgebung ab. Möglicherweise möchten Sie dieses Problem in WriteConcern.JOURNALED (auf oplog geschrieben) oder WriteConcern.FSYNCED (auf die Festplatte geschrieben) oder sogar in Replikatsätze (Backups) ändern. wenn es benötigt wird.

Dann kann es zu Leistungseinbußen kommen. Weitere wichtige Faktoren sind die Optimierung Ihrer Datenzugriffsmuster, der Indexfehler% (siehe Mongostat ) und die Indizes im Allgemeinen.

schwarz
quelle
0

Ich denke, dass das 2-3X auf dem gezeigten Benchmark irreführend ist, denn wenn Sie es auch von der Hardware abhängen, auf der Sie es ausführen - meiner Erfahrung nach ist die Lücke umso größer, je stärker die Maschine ist (zugunsten von Redis). wird sein, wahrscheinlich durch die Tatsache, dass der Benchmark die Speichergrenzen ziemlich schnell erreicht.

Was die Speicherkapazität betrifft, so ist dies teilweise richtig, da es auch Möglichkeiten gibt, dies zu umgehen. Es gibt (kommerzielle) Produkte, die Redis-Daten auf die Festplatte zurückschreiben, sowie Cluster-Lösungen (Multi-Sharded), die die Speichergröße überwinden Einschränkung.

Elior Malul
quelle