¿Cuánto más rápido es Redis que mongoDB?

204

Se menciona ampliamente que Redis es "Blazing Fast" y mongoDB también es rápido. Pero tengo problemas para encontrar números reales comparando los resultados de los dos. Dadas configuraciones, características y operaciones similares (y tal vez mostrando cómo cambia el factor con diferentes configuraciones y operaciones), etc., ¿Redis es 10 veces más rápido ?, ¿2 veces más rápido ?, ¿5 veces más rápido?

Solo estoy hablando de rendimiento. Entiendo que mongoDB es una herramienta diferente y tiene un conjunto de características más rico. Este no es el debate "Es mongoDB mejor que Redis". Estoy preguntando, ¿por qué margen Redis supera a mongoDB?

En este punto, incluso los puntos de referencia baratos son mejores que ningún punto de referencia.

Homero6
fuente
10
Los puntos de referencia baratos siempre son mejores que ningún punto de referencia. Gracias por la pregunta amigo.
Maziyar
2
En general, preocuparse por la diferencia entre 5,000 operaciones / seg y 10,000 operaciones / seg es a menudo un caso de optimización prematura. Dicho esto, sigue siendo una respuesta interesante :)
Kevin

Respuestas:

238

Resultados aproximados del siguiente punto de referencia: 2x escritura, 3x lectura .

Aquí hay un punto de referencia simple en Python que puede adaptar a sus propósitos. Estaba mirando qué tan bien funcionaría cada uno simplemente configurando / recuperando valores:

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

Resultados para con mongodb 1.8.1 y redis 2.2.5 y la última versión de 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

Tome los resultados con un grano de sal, por supuesto! Si está programando en otro lenguaje, utilizando otros clientes / implementaciones diferentes, etc., sus resultados variarán enormemente. ¡Sin mencionar que su uso será completamente diferente! Su mejor opción es compararlos usted mismo, precisamente en la forma en que tiene la intención de usarlos. Como corolario, probablemente descubras la mejor manera de hacer uso de cada uno. Siempre punto de referencia para usted!

zeekay
fuente
3
Vale la pena comentar que MongoDB y Redis tienen estructuras de persistencia diferentes, y que Redis solo admite un esquema de datos que puede caber en la memoria. Aunque la memoria RAM es barata, si necesita usar / almacenar más de 12-16 GB de datos, vería cómo se ven las opciones de su servidor.
Rastreador1
53
@sivann esta publicación va de ningún punto de referencia a un punto de referencia "aproximado" claramente establecido. No seas un troll con las tonterías de "los puntos de referencia son engañosos". Por supuesto, diferentes condiciones pueden alterar los resultados. Contribuya de nuevo y envíe sus propios puntos de referencia que prueben su caso y enlace desde esta publicación, luego todos nos beneficiaremos de su opinión "probada".
Homer6
2
@sivann La configuración predeterminada (enviada) es lo que este punto de referencia estaba probando. En mi humilde opinión, la configuración predeterminada determina en qué lado de la cerca fsync se encuentra un paquete. Para Redis, se anuncia como un servidor de memoria que insta a las personas a usar otras alternativas cuando la base de datos es más grande que la memoria total del sistema. Para MongoDB, se anuncia como una base de datos. Postgres nunca apagaría fsync porque están claramente en el campo de persistencia. La mayoría de las personas no modifican las configuraciones, por lo que este punto de referencia es algo preciso para esos casos.
Homer6
44
Estoy de acuerdo con @sivann, el punto de referencia que publicaste es fatalmente defectuoso. MongoDB es multiproceso y Redis no lo es. Si su punto de referencia fuera de subprocesos múltiples, vería que MongoDb en realidad tiene un mayor rendimiento en una máquina de múltiples núcleos.
ColinM
2
@ Homer6 incluso para DB orientado a memoria, debe probar con WriteConcern habilitado (deshabilitado por defecto). Probar sin es realmente una tontería para cualquier tipo de punto de referencia. Similar para reddis. Las bases de datos que no sincronizan en el disco todas las transacciones, mantienen la seguridad al replicar los datos en al menos 2 servidores. Eso significa que sus escrituras no esperan una sincronización de disco, sino la replicación de la red antes de regresar. No esperar errores es algo que nunca se hace en productos. como no detectar si el cable de red está conectado al escribir en la red.
sivann
18

Consulte esta publicación sobre el análisis de rendimiento de inserción de Redis y MongoDB:

Hasta 5000 entradas mongodb $ push es más rápido incluso en comparación con Redis RPUSH, entonces se vuelve increíblemente lento, probablemente el tipo de matriz mongodb tiene un tiempo de inserción lineal y, por lo tanto, se vuelve más y más lento. mongodb podría ganar un poco de rendimiento al exponer un tipo de lista de inserción de tiempo constante, pero incluso con el tipo de matriz de tiempo lineal (que puede garantizar una búsqueda de tiempo constante) tiene sus aplicaciones para pequeños conjuntos de datos.

Andrei Andrushkevich
fuente
15

Punto de referencia bueno y simple

Traté de recalcular los resultados nuevamente usando las versiones actuales de redis (2.6.16) y mongo (2.4.8) y aquí está el resultado

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

Además, esta publicación de blog los compara a ambos, pero usando node.js. Muestra el efecto de aumentar el número de entradas en la base de datos junto con el tiempo.

Tareq Salah
fuente
8

Los números serán difíciles de encontrar ya que los dos no están en el mismo espacio. La respuesta general es que Redis es 10-30% más rápido cuando el conjunto de datos se ajusta a la memoria de trabajo de una sola máquina. Una vez que se excede esa cantidad de datos, Redis falla. Mongo disminuirá la velocidad en una cantidad que depende del tipo de carga. Para un tipo de carga de inserción solamente, un usuario informó recientemente una desaceleración de 6 a 7 órdenes de magnitud (10,000 a 100,000 veces) pero ese informe también admitió que hubo problemas de configuración, y que esta era una carga de trabajo muy atípica. Las cargas pesadas de lectura normal son anecdóticamente lentas en aproximadamente 10X cuando algunos de los datos deben leerse desde el disco.

Conclusión: Redis será más rápido pero no mucho.

John F. Miller
fuente
7

Aquí hay un excelente artículo sobre el rendimiento de la sesión en el marco Tornado de aproximadamente 1 año de edad. Tiene una comparación entre algunas implementaciones diferentes, de las cuales se incluyen Redis y MongoDB. El gráfico en el artículo establece que Redis está detrás de MongoDB en aproximadamente un 10% en este caso de uso específico.

Redis viene con un punto de referencia incorporado que analizará el rendimiento de la máquina en la que se encuentra. Hay una tonelada de datos sin procesar en el wiki de Benchmark para Redis. Pero es posible que tengas que buscar un poco a Mongo. Como aquí , aquí y algunos números de pulido aleatorios (pero le da un punto de partida para ejecutar algunos puntos de referencia MongoDB usted mismo).

Creo que la mejor solución a este problema es realizar las pruebas usted mismo en los tipos de situaciones que espera.

equivocados
fuente
Los puntos de referencia de Tornado se alinean bien con mis propias pruebas al usar Redis y MongoDb como un backend de Zend_Cache. La funcionalidad más rica de MongoDb le permite usar menos solicitudes y el diseño multiproceso se escala mucho mejor que un solo proceso Redis que no es multiproceso. La conclusión es que MongoDb escala más alto. Además, Redis ya no es compatible con la memoria virtual.
ColinM
3

En mi caso, lo que ha sido un factor determinante en la comparación de rendimiento es el MongoDb WriteConcern que se utiliza. La mayoría de los controladores de mongo hoy en día establecerán el WriteConcern predeterminado en ACKNOWLEDGED, que significa 'escrito en RAM' ( Mongo2.6.3-WriteConcern ), en ese sentido, fue muy comparable a redis para la mayoría de las operaciones de escritura.

Pero la realidad depende de las necesidades de su aplicación y la configuración del entorno de producción, es posible que desee cambiar esta preocupación a WriteConcern.JOURNALED (escrito en oplog) o WriteConcern.FSYNCED (escrito en el disco) o incluso escrito en conjuntos de réplica (copias de seguridad) Si es necesario.

Entonces puede comenzar a ver una disminución en el rendimiento. Otros factores importantes también incluyen, qué tan optimizados están sus patrones de acceso a datos,% de falta de índice (ver mongostat ) e índices en general.

Schwarz
fuente
0

Creo que los 2-3X en el punto de referencia mostrado son engañosos, ya que si usted también depende del hardware en el que lo ejecuta, según mi experiencia, cuanto más fuerte sea la máquina, mayor será la brecha (a favor de Redis) será, probablemente por el hecho de que el punto de referencia alcanza el límite de los límites de memoria bastante rápido.

En cuanto a la capacidad de memoria, esto es parcialmente cierto, ya que también hay formas de evitarlo, hay productos (comerciales) que vuelven a escribir los datos de Redis en el disco, y también soluciones de clúster (múltiples fragmentos) que superan el tamaño de la memoria limitación.

Elior Malul
fuente