Combien plus rapide est Redis que mongoDB?

204

Il est largement mentionné que Redis est "Blazing Fast" et mongoDB est rapide aussi. Mais, j'ai du mal à trouver des chiffres réels en comparant les résultats des deux. Étant donné des configurations, des fonctionnalités et des opérations similaires (et peut-être montrant comment le facteur change avec différentes configurations et opérations), etc., Redis est-il 10 fois plus rapide?, 2x plus rapide?, 5 fois plus rapide?

Je ne parle que de performance. Je comprends que mongoDB est un outil différent et possède un ensemble de fonctionnalités plus riche. Ce n'est pas le débat "Est-ce que mongoDB est meilleur que Redis". Je demande, par quelle marge Redis surpasse-t-il mongoDB?

À ce stade, même des indices de référence bon marché sont meilleurs que aucun indice de référence.

Homer6
la source
10
Les benchmarks bon marché sont toujours meilleurs que pas de benchmarks. Merci pour la question mate.
Maziyar
2
En général, se soucier de la différence entre 5 000 ops / sec et 10 000 ops / sec est souvent un cas d'optimisation prématurée. Cela dit, c'est toujours une réponse intéressante :)
Kevin

Réponses:

238

Résultats approximatifs du benchmark suivant: 2x écriture, 3x lecture .

Voici un benchmark simple en python que vous pouvez adapter à vos besoins, je cherchais à quel point chacun effectuerait simplement la définition / récupération de valeurs:

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

Résultats pour avec mongodb 1.8.1 et redis 2.2.5 et les derniers 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

Prenez les résultats avec un grain de sel bien sûr! Si vous programmez dans un autre langage, en utilisant d'autres clients / implémentations différentes, etc., vos résultats varieront de manière extravagante. Sans oublier que votre utilisation sera complètement différente! Votre meilleur pari est de les comparer vous-même, précisément de la manière dont vous avez l'intention de les utiliser. En corollaire, vous découvrirez probablement la meilleure façon de les utiliser. Toujours une référence pour vous-même!

Zeekay
la source
3
Il convient de noter que MongoDB et Redis ont des structures de persistance différentes et que Redis prend uniquement en charge un schéma de données capable de tenir en mémoire. Bien que ram soit bon marché, si vous devez utiliser / stocker plus de 12 à 16 Go de données, je verrais à quoi ressemblent vos options de serveur.
Tracker1
53
@sivann cet article passe de l'absence de référence à une référence "approximative" clairement indiquée. Ne soyez pas un troll avec le non-sens "les repères sont trompeurs". Bien entendu, des conditions différentes peuvent modifier les résultats. Contribuez en retour et soumettez vos propres repères qui testent votre cas et liez à partir de ce message, alors nous bénéficierons tous de votre opinion "testée".
Homer6
2
@sivann La configuration par défaut (fournie) correspond à ce que ce test testait. À mon humble avis, la configuration par défaut détermine de quel côté de la clôture fsync un paquet se trouve. Pour Redis, il est annoncé comme un serveur de mémoire qui invite les gens à utiliser d'autres alternatives lorsque la base de données est supérieure à la mémoire système totale. Pour MongoDB, il est annoncé comme une base de données. Postgres ne désactiverait jamais fsync car ils sont clairement dans le camp de persistance. La plupart des gens ne modifient pas les configurations, donc cette référence est quelque peu précise pour ces cas.
Homer6
4
Je suis d'accord avec @sivann, l'indice de référence que vous avez publié est fatalement défectueux. MongoDB est multi-thread et Redis ne l'est pas. Si votre benchmark était multi-thread, vous verriez que MongoDb a en fait un débit plus élevé sur une machine multi-core.
ColinM
2
@ Homer6 même pour les bases de données orientées mémoire, vous devez tester avec WriteConcern activé (désactivé par défaut). Tester sans est un non-sens pour tout type de référence. Similaire pour reddis. Les bases de données qui ne synchronisent pas sur le disque toutes les transactions maintiennent la sécurité en répliquant les données sur au moins 2 serveurs. Cela signifie que vos écritures n'attendent pas une synchronisation de disque, mais une réplication réseau avant de revenir. Ne pas attendre les erreurs est quelque chose de jamais fait sur prod. comme ne pas détecter si le câble réseau est connecté lors de l'écriture sur le réseau.
sivann
18

Veuillez consulter cet article sur l'analyse des performances d'insertion de Redis et MongoDB:

Jusqu'à 5000 entrées mongodb $ push est plus rapide même par rapport à Redis RPUSH, puis il devient incroyablement lent, probablement le type de tableau mongodb a un temps d'insertion linéaire et donc il devient de plus en plus lent. mongodb peut gagner un peu de performances en exposant un type de liste d'insertion à temps constant, mais même avec le type de tableau de temps linéaire (qui peut garantir une recherche à temps constant), il a ses applications pour de petits ensembles de données.

Andrei Andrushkevich
la source
15

Bon et simple benchmark

J'ai essayé de recalculer les résultats à nouveau en utilisant les versions actuelles de redis (2.6.16) et mongo (2.4.8) et voici le résultat

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

De plus, ce billet de blog les compare, mais en utilisant node.js. Il montre l'effet de l'augmentation du nombre d'entrées dans la base de données avec le temps.

Tareq Salah
la source
8

Les nombres vont être difficiles à trouver car les deux ne sont pas tout à fait dans le même espace. La réponse générale est que Redis est 10 à 30% plus rapide lorsque l'ensemble de données tient dans la mémoire de travail d'une seule machine. Une fois cette quantité de données dépassée, Redis échoue. Mongo ralentira à une quantité qui dépend du type de charge. Pour un type de charge d'insertion uniquement, un utilisateur a récemment signalé un ralentissement de 6 à 7 ordres de grandeur (10 000 à 100 000 fois), mais ce rapport a également admis qu'il y avait des problèmes de configuration et qu'il s'agissait d'une charge de travail très atypique. Les charges lourdes de lecture normale sont anecdotiquement lentes d'environ 10 fois lorsque certaines données doivent être lues sur le disque.

Conclusion: Redis sera plus rapide mais pas beaucoup.

John F. Miller
la source
7

Voici un excellent article sur les performances des sessions dans le framework Tornado d'environ 1 an. Il a une comparaison entre quelques implémentations différentes, dont Redis et MongoDB sont inclus. Le graphique de l'article indique que Redis est derrière MongoDB d'environ 10% dans ce cas d'utilisation spécifique.

Redis est livré avec une référence intégrée qui analysera les performances de la machine sur laquelle vous vous trouvez. Il y a une tonne de données brutes sur le wiki Benchmark pour Redis. Mais vous devrez peut-être chercher un peu Mongo. Comme ici , ici et quelques chiffres aléatoires (mais cela vous donne un point de départ pour exécuter vous-même certains benchmarks MongoDB).

Je crois que la meilleure solution à ce problème est d'effectuer les tests vous-même dans les types de situations que vous attendez.

mistagrooves
la source
Les benchmarks Tornado s'alignent bien avec mes propres tests en utilisant Redis et MongoDb comme backend Zend_Cache. La fonctionnalité plus riche de MongoDb vous permet d'utiliser moins de demandes et la conception multi-thread évolue bien mieux qu'un seul processus Redis qui n'est pas multi-thread. La conclusion est que MongoDb évolue plus haut. De plus, Redis ne prend plus en charge la mémoire virtuelle.
ColinM
3

Dans mon cas, ce qui a été un facteur déterminant dans la comparaison des performances, c'est le MongoDb WriteConcern qui est utilisé. De nos jours, la plupart des pilotes mongo définissent WriteConcern par défaut sur ACKNOWLEDGED, ce qui signifie `` écrit sur RAM '' ( Mongo2.6.3-WriteConcern ), à cet égard, il était très comparable à redis pour la plupart des opérations d'écriture.

Mais la réalité dépend des besoins de votre application et de la configuration de l'environnement de production, vous souhaiterez peut-être changer ce problème en WriteConcern.JOURNALED (écrit sur oplog) ou WriteConcern.FSYNCED (écrit sur disque) ou même écrit sur des jeux de réplicas (sauvegardes) si c'est nécessaire.

Ensuite, vous pouvez commencer à voir une baisse des performances. D'autres facteurs importants incluent également l'optimisation de vos modèles d'accès aux données, l'index% de manque (voir mongostat ) et les index en général.

schwarz
la source
0

Je pense que les 2-3X sur l'indice de référence indiqué sont trompeurs, car si vous dépend aussi du matériel sur lequel vous l'utilisez - d'après mon expérience, plus la machine est `` solide '', plus l'écart est grand (en faveur de Redis) sera, probablement par le fait que le benchmark atteint la limite de mémoire assez rapidement.

En ce qui concerne la capacité de mémoire - cela est partiellement vrai, car il existe également des moyens de contourner cela, il existe des produits (commerciaux) qui réécrit les données Redis sur le disque, ainsi que des solutions de cluster (multi-partitionnées) qui dépassent la taille de la mémoire limitation.

Elior Malul
la source