Quanto è più veloce Redis di mongoDB?


204

È ampiamente menzionato che Redis è "Blazing Fast" e mongoDB è anche veloce. Ma ho problemi a trovare i numeri reali confrontando i risultati dei due. Date configurazioni, caratteristiche e operazioni simili (e forse mostrando come cambia il fattore con configurazioni e operazioni diverse), ecc. Redis è 10 volte più veloce? 2x più veloce? 5 volte più veloce?

Sto parlando SOLO di performance. Capisco che mongoDB è uno strumento diverso e ha un set di funzionalità più ricco. Questo non è il dibattito "Is mongoDB better than Redis". Sto chiedendo, con quale margine Redis supera le prestazioni di mongoDB?

A questo punto, anche i benchmark economici sono migliori di nessun benchmark.


10
I benchmark economici sono sempre meglio di nessun benchmark. Grazie per la domanda amico.
Maziyar,

2
In generale, preoccuparsi della differenza tra 5.000 operazioni / sec e 10.000 operazioni / sec è spesso un caso di ottimizzazione prematura. Detto questo, è ancora una risposta interessante :)
Kevin,

Risposte:


238

Risultati approssimativi dal seguente benchmark: 2x write, 3x read .

Ecco un semplice punto di riferimento in Python che puoi adattare ai tuoi scopi, stavo guardando quanto ciascuno avrebbe funzionato semplicemente impostando / recuperando valori:

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

Risultati per con mongodb 1.8.1 e redis 2.2.5 e gli ultimi 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

Prendi i risultati con un granello di sale ovviamente! Se stai programmando in un'altra lingua, usando altri client / implementazioni diverse, ecc. I tuoi risultati varieranno selvaggiamente. Per non parlare del fatto che il tuo utilizzo sarà completamente diverso! La tua scommessa migliore è di confrontarli da soli, esattamente nel modo in cui intendi utilizzarli. Come corollario probabilmente troverai il modo migliore per farne uso. Sempre benchmark per te!


3
Vale la pena di commentare che MongoDB e Redis hanno strutture di persistenza diverse e che Redis supporta solo uno schema di dati in grado di adattarsi alla memoria. Sebbene ram sia economico, se è necessario utilizzare / archiviare più di 12-16 GB di dati, vedrei come appaiono le opzioni del tuo server.
Tracker1

53
@sivann questo post va da nessun benchmark a un benchmark "approssimativo" chiaramente dichiarato. Non essere un troll con le sciocchezze "i benchmark sono fuorvianti". Naturalmente condizioni diverse possono alterare i risultati. Contribuisci indietro e invia i tuoi parametri di riferimento che testano il tuo caso e link da questo post, quindi trarremo tutti vantaggio dalla tua opinione "testata".
Homer6

2
@sivann La configurazione predefinita (spedita) è ciò che questo benchmark stava testando. IMHO, la configurazione predefinita determina da quale parte del recinto fsync si trova un pacchetto. Per Redis, è pubblicizzato come un server di memoria che esorta le persone a utilizzare altre alternative quando il database è più grande della memoria di sistema totale. Per MongoDB, è pubblicizzato come un database. Postgres non disattiverà mai fsync perché sono chiaramente nel campo di persistenza. La maggior parte delle persone non modifica le configurazioni, quindi questo benchmark è in qualche modo accurato per quei casi.
Homer6

4
Sono d'accordo con @sivann, il benchmark che hai pubblicato è fatalmente imperfetto. MongoDB è multi-thread e Redis no. Se il tuo benchmark fosse multi-thread vedresti che MongoDb ha effettivamente un throughput più elevato su una macchina multi-core.
ColinM,

2
@ Homer6 anche per DB orientati alla memoria, è necessario testare con WriteConcern abilitato (disabilitato per impostazione predefinita). Il test senza è davvero una sciocchezza per qualsiasi tipo di benchmark. Simile per i rossi. I DB che non sincronizzano su disco tutte le transazioni, mantengono la sicurezza replicando i dati su almeno 2 server. Ciò significa che le tue scritture non attendono la sincronizzazione del disco, ma la replica di rete prima di tornare. Non aspettare errori è qualcosa che non viene mai fatto su prod. come non rilevare se il cavo di rete è collegato quando si scrive sulla rete.
sivann,

18

Si prega di controllare questo post sull'analisi delle prestazioni di inserimento Redis e MongoDB:

Fino a 5000 voci mongodb $ push è più veloce anche rispetto a Redis RPUSH, quindi diventa incredibilmente lento, probabilmente il tipo di array mongodb ha un tempo di inserimento lineare e quindi diventa sempre più lento. mongodb potrebbe ottenere un po 'di prestazioni esponendo un tipo di elenco di inserimento temporale costante, ma anche con il tipo di array di tempo lineare (che può garantire una ricerca temporale costante) ha le sue applicazioni per piccoli insiemi di dati.


15

Punto di riferimento buono e semplice

Ho provato a ricalcolare nuovamente i risultati usando le versioni attuali di redis (2.6.16) e mongo (2.4.8) ed ecco il risultato

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

Anche questo post sul blog li confronta entrambi ma usando node.js. Mostra l'effetto di un numero crescente di voci nel database insieme al tempo.


8

I numeri saranno difficili da trovare poiché i due non si trovano nello stesso spazio. La risposta generale è che Redis è più veloce del 10-30% quando il set di dati si adatta alla memoria di lavoro di una singola macchina. Una volta superata tale quantità di dati, Redis ha esito negativo. Mongo rallenterà di un importo che dipende dal tipo di carico. Per un solo tipo di carico di inserimento un utente ha recentemente riportato un rallentamento di 6-7 ordini di grandezza (da 10.000 a 100.000 volte), ma tale rapporto ha anche ammesso che c'erano problemi di configurazione e che si trattava di un carico di lavoro molto atipico. La lettura normale di carichi pesanti rallenta aneddoticamente di circa 10X quando alcuni dei dati devono essere letti dal disco.

Conclusione: Redis sarà più veloce ma non di molto.


7

Ecco un eccellente articolo sulle prestazioni della sessione nel framework Tornado di circa 1 anno. Ha un confronto tra alcune diverse implementazioni, tra cui Redis e MongoDB sono inclusi. Il grafico nell'articolo afferma che Redis è dietro MongoDB di circa il 10% in questo caso d'uso specifico.

Redis viene fornito con un benchmark integrato che analizzerà le prestazioni della macchina su cui ci si trova. Ci sono un sacco di dati grezzi da esso nel wiki Benchmark per Redis. Ma potresti doverti guardare un po 'in giro per Mongo. Come qui , qui e alcuni numeri polacchi casuali (ma ti dà un punto di partenza per eseguire tu stesso alcuni benchmark MongoDB).

Credo che la migliore soluzione a questo problema sia quella di eseguire i test da soli nei tipi di situazioni che ci si aspetta.


I benchmark Tornado si allineano bene con i miei test usando Redis e MongoDb come backend di Zend_Cache. La più ricca funzionalità di MongoDb consente di utilizzare un minor numero di richieste e il design multi-thread si adatta molto meglio di un singolo processo Redis che non è multi-thread. La conclusione è che MongoDb si ridimensiona. Inoltre, Redis non supporta più la memoria virtuale.
ColinM,

3

Nel mio caso, ciò che è stato un fattore determinante nel confronto delle prestazioni, è MongoDb WriteConcern che viene utilizzato. La maggior parte dei driver mongo oggigiorno imposterà WriteConcern predefinito su ACKNOWLEDGED che significa "scritto su RAM" ( Mongo2.6.3-WriteConcern ), a questo proposito, era molto paragonabile a redis per la maggior parte delle operazioni di scrittura.

Ma la realtà dipende dalle esigenze dell'applicazione e dall'impostazione dell'ambiente di produzione, è possibile che si desideri modificare questa preoccupazione in WriteConcern.JOURNALED (scritto su oplog) o WriteConcern.FSYNCED (scritto su disco) o addirittura scritto su set di repliche (backup) se è necessario.

Quindi potresti iniziare a vedere un certo calo delle prestazioni. Altri fattori importanti includono anche quanto sono ottimizzati i modelli di accesso ai dati, indice% mancata (vedi mongostat ) e indici in generale.


0

Penso che il 2-3X sul benchmark mostrato sia fuorviante, poiché se dipende anche dall'hardware su cui lo si esegue - dalla mia esperienza, più "forte" è la macchina, maggiore è il divario (a favore di Redis) sarà, probabilmente per il fatto che il benchmark raggiunge i limiti di memoria abbastanza velocemente.

Per quanto riguarda la capacità di memoria - questo è parzialmente vero, poiché ci sono anche modi per aggirarlo, ci sono prodotti (commerciali) che riscrivono i dati Redis su disco e anche soluzioni cluster (multi-sharded) che superano le dimensioni della memoria limitazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.