Quanto mais rápido o Redis é o mongoDB?

204

É amplamente mencionado que o Redis é "Blazing Fast" e o mongoDB também é rápido. Mas, estou tendo problemas para encontrar números reais comparando os resultados dos dois. Dadas configurações, recursos e operações semelhantes (e talvez mostrando como o fator muda com diferentes configurações e operações), etc., o Redis é 10x mais rápido ?, 2x mais rápido?, 5x mais rápido?

Estou falando apenas de desempenho. Entendo que o mongoDB é uma ferramenta diferente e possui um conjunto de recursos mais rico. Este não é o debate "O mongoDB é melhor que o Redis"? Estou perguntando, por qual margem o Redis supera o mongoDB?

Neste ponto, mesmo os benchmarks baratos são melhores do que nenhum benchmark.

Homer6
fonte
10
Benchmarks baratos são sempre melhores que nenhum benchmark. Obrigado pela pergunta companheiro.
Maziyar 22/03
2
Em geral, cuidar da diferença entre 5.000 ops / s e 10.000 ops / s é geralmente um caso de otimização prematura. Dito isto, ainda é uma resposta interessante :) #
2222 Kevin Kevin

Respostas:

238

Resultados aproximados da seguinte referência: gravação de 2x, leitura de 3x .

Aqui está uma referência simples em python, que você pode adaptar aos seus propósitos, eu estava vendo como cada um executaria simplesmente 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 com mongodb 1.8.1 e redis 2.2.5 e o mais recente 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

Leve os resultados com um grão de sal, é claro! Se você estiver programando em outro idioma, usando outros clientes / implementações diferentes, etc., seus resultados variarão rapidamente. Sem mencionar que o seu uso será completamente diferente! Sua melhor aposta é compará-los você mesmo, exatamente da maneira que você pretende usá-los. Como corolário, você provavelmente descobrirá a melhor maneira de fazer uso de cada um. Sempre referência para si mesmo!

zeekay
fonte
3
Vale a pena comentar que o MongoDB e o Redis têm estruturas de persistência diferentes e que o Redis suporta apenas um esquema de dados capaz de caber na memória. Embora o ram seja barato, se você precisar usar / armazenar mais de 12 a 16 GB de dados, eu veria como são as opções do servidor.
precisa
53
@sivann este post não passa de benchmarks para um benchmark "áspero" claramente declarado. Não seja um troll com as bobagens "referências são enganosas". É claro que condições diferentes podem alterar os resultados. Contribua e envie seus próprios benchmarks que testam seu caso e vinculam a partir desta postagem. Todos nós nos beneficiaremos da sua opinião "testada".
precisa saber é o seguinte
2
@sivann A configuração padrão (enviada) é o que este benchmark estava testando. IMHO, a configuração padrão determina em que lado da cerca do fsync um pacote fica. Para o Redis, ele é anunciado como um servidor de memória que incentiva as pessoas a usar outras alternativas quando o banco de dados for maior que a memória total do sistema. Para o MongoDB, é anunciado como um banco de dados. O Postgres nunca desativaria o fsync porque está claramente no campo de persistência. A maioria das pessoas não modifica as configurações, portanto, essa referência é um pouco precisa para esses casos.
Homer6
4
Concordo com @sivann, a referência que você postou é fatalmente falha. O MongoDB é multiencadeado e o Redis não. Se o seu benchmark fosse multiencadeado, você perceberia que o MongoDb realmente tem maior rendimento em uma máquina com vários núcleos.
ColinM
2
@ Homer6, mesmo para o banco de dados orientado à memória, você deve testar com o WriteConcern ativado (desativado por padrão). Testar sem é realmente um absurdo para qualquer tipo de referência. Semelhante para reddis. Os bancos de dados que não sincronizam todas as transações no disco mantêm a segurança replicando os dados em pelo menos 2 servidores. Isso significa que suas gravações não esperam pela sincronização do disco, mas pela replicação da rede antes de retornar. Não esperar por erros é algo que nunca é feito no prod. como não detectar se o cabo de rede está conectado ao escrever na rede.
sivann
18

Verifique este post sobre a análise de desempenho de inserção de Redis e MongoDB:

Até 5.000 entradas o mongodb $ push é mais rápido, mesmo quando comparado ao Redis RPUSH, então fica incrivelmente lento, provavelmente o tipo de matriz mongodb tem tempo de inserção linear e, portanto, fica cada vez mais lento. O mongodb pode obter um pouco de desempenho, expondo um tipo de lista de inserção de tempo constante, mas mesmo com o tipo de matriz de tempo linear (que pode garantir a busca constante de tempo), ele tem seus aplicativos para pequenos conjuntos de dados.

Andrei Andrushkevich
fonte
15

Benchmark bom e simples

Tentei recalcular os resultados novamente usando as versões atuais de redis (2.6.16) e mongo (2.4.8) e aqui está o 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

Além disso, este post compara os dois, mas usando o node.js. Ele mostra o efeito do aumento do número de entradas no banco de dados junto com o tempo.

Tareq Salah
fonte
8

Os números serão difíceis de encontrar, pois os dois não estão exatamente no mesmo espaço. A resposta geral é que o Redis é 10 a 30% mais rápido quando o conjunto de dados se encaixa na memória de trabalho de uma única máquina. Depois que essa quantidade de dados é excedida, o Redis falha. O Mongo diminuirá a velocidade a uma quantidade que depende do tipo de carga. Para um tipo de carga apenas de inserção, um usuário relatou recentemente uma desaceleração de 6 a 7 ordens de magnitude (10.000 a 100.000 vezes), mas esse relatório também admitiu que havia problemas de configuração e que essa era uma carga de trabalho muito atípica. As cargas pesadas de leitura normal são anedoticamente lentas em cerca de 10X quando alguns dos dados devem ser lidos do disco.

Conclusão: os Redis serão mais rápidos, mas não muito.

John F. Miller
fonte
7

Aqui está um excelente artigo sobre o desempenho da sessão no framework Tornado, com cerca de 1 ano de idade. Ele tem uma comparação entre algumas implementações diferentes, das quais Redis e MongoDB estão incluídos. O gráfico no artigo afirma que o Redis está atrás do MongoDB em cerca de 10% neste caso de uso específico.

O Redis vem com um benchmark integrado que analisará o desempenho da máquina em que você está. Existe uma tonelada de dados brutos no wiki do Benchmark para Redis. Mas talvez você precise procurar um pouco pelo Mongo. Como aqui , aqui e alguns números aleatórios de polimento (mas fornece um ponto de partida para a execução de alguns benchmarks do MongoDB).

Acredito que a melhor solução para esse problema é realizar os testes você mesmo nos tipos de situações que você espera.

mistagrooves
fonte
Os benchmarks do Tornado se alinham bem com meus próprios testes ao usar Redis e MongoDb como um backend do Zend_Cache. A funcionalidade mais rica do MongoDb permite que você use menos solicitações e o design multithread é dimensionado muito melhor do que um único processo Redis que não é multithread. A conclusão é que o MongoDb é mais alto. Além disso, o Redis não oferece mais suporte à memória virtual.
ColinM
3

No meu caso, o que tem sido um fator determinante na comparação de desempenho, é o MongoDb WriteConcern usado. Atualmente, a maioria dos drivers mongo define o WriteConcern padrão como ACKNOWLEDGED, o que significa 'gravado na RAM' ( Mongo2.6.3-WriteConcern ); nesse sentido, era muito comparável ao redis para a maioria das operações de gravação.

Mas a realidade depende das necessidades do aplicativo e da configuração do ambiente de produção. Você pode alterar essa preocupação para WriteConcern.JOURNALED (gravado em oplog) ou WriteConcern.FSYNCED (gravado em disco) ou até gravado em conjuntos de réplicas (backups) se for necessário.

Então você pode começar a ver uma diminuição no desempenho. Outros fatores importantes também incluem, quão otimizados são seus padrões de acesso a dados,% de índice faltante (consulte mongostat ) e índices em geral.

schwarz
fonte
0

Eu acho que os 2-3X na referência mostrada são enganosos, pois se você também depende do hardware em que é executado - pela minha experiência, quanto mais forte a máquina é, maior a diferença (a favor da Redis) será, provavelmente pelo fato de que o benchmark atinge os limites de memória muito rapidamente.

Quanto à capacidade de memória - isso é parcialmente verdade, já que também existem maneiras de contornar isso, existem produtos (comerciais) que gravam dados Redis em disco e também soluções de cluster (multi-sharded) que superam o tamanho da memória limitação.

Elior Malul
fonte