Redis比mongoDB快多少?


204

人们普遍认为Redis的速度非常快,而mongoDB的速度也很快。但是,我很难找到比较两者结果的实际数字。给定类似的配置,功能和操作(并可能显示因不同的配置和操作而导致的因素变化)等,Redis是10倍速,2倍速,5倍速吗?

我只说性能。我知道mongoDB是另一种工具,具有更丰富的功能集。这不是“ MongoDB 比Redis 更好 ”的争论。我问的是,Redis在性能上胜过mongoDB?

在这一点上,即使是便宜的基准也比没有基准要好。


10
便宜的基准总是比没有基准更好。谢谢你的队友。
Maziyar 2013年

2
通常,关心5,000 ops / sec和10,000 ops / sec之间的差异通常是过早优化的情况。话虽如此,它仍然是一个有趣的答案:)
凯文(Kevin)

Answers:


238

来自以下基准的粗略结果:2倍写入,3倍读取

这是一个可以适应您的目的的简单python基准测试,我正在研究每个参数在简单地设置/检索值方面的表现如何:

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

mongodb 1.8.1和redis 2.2.5以及最新的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

当然要加一点盐!如果您使用另一种语言进行编程,使用其他客户端/不同的实现方式等,则结果将大相径庭。更不用说您的用法将完全不同!最好的选择是按照自己打算使用它们的方式对它们进行基准测试。作为推论,您可能会想出利用每种方法的最佳方法。始终为自己设定基准!


3
值得一提的是MongoDB和Redis具有不同的持久性结构,并且Redis仅支持能够容纳在内存中的数据模式。虽然ram便宜,但是如果您需要使用/存储超过12-16GB的数据,我将看到您的服务器选项是什么样的。
Tracker1 2012年

53
@sivann这篇文章从没有基准变为明确说明的“粗略”基准。不要以“基准误导”胡说八道。当然,不同的条件会改变结果。回馈并提交您自己的基准测试,以测试您的案例并通过这篇文章链接,然后我们都会从您的“经过测试的”意见中受益。
2013年

2
@sivann默认(出厂)配置是此基准测试的内容。恕我直言,默认配置确定程序包位于fsync栅栏的哪一侧。对于Redis,它被宣传为内存服务器,当数据库大于系统总内存时,它敦促人们使用其他替代方案。对于MongoDB,它被宣传为数据库。Postgres永远不会关闭fsync,因为它们显然处于持久性阵营中。大多数人不修改配置,因此此基准在某些情况下是准确的。
2013年

4
我同意@sivann,您发布的基准存在致命缺陷。MongoDB是多线程的,而Redis不是。如果您的基准测试是多线程的,您会发现MongoDb实际上在多核计算机上具有更高的吞吐量。
ColinM 2013年

2
@ Homer6即使对于面向内存的数据库,也应该在启用WriteConcern的情况下进行测试(默认情况下处于禁用状态)。对于任何类型的基准测试,没有测试确实是胡说八道。与reddis类似。未在磁盘上同步所有事务的DB通过将数据复制到至少2台服务器来维护安全性。这意味着您的写入操作不会等待磁盘同步,而是等待网络复制后再返回。不等待错误是生产中从未做过的事情。就像在写入网络时不检测网络电缆是否已连接。
sivann 2013年

18

请检查有关Redis和MongoDB插入性能分析的帖子

即使与Redis RPUSH相比,多达5000个条目的mongodb $ push也更快,然后变得非常慢,可能mongodb数组类型具有线性插入时间,因此变得越来越慢。mongodb通过公开一个恒定时间插入列表类型可能会获得一些性能,但是即使使用线性时间数组类型(可以保证恒定时间查找),它也可以用于少量数据集。


15

简单好基准

我尝试使用当前版本的redis(2.6.16)和mongo(2.4.8)再次重新计算结果,这是结果

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

此外,此博客文章还使用node.js比较了两者。它显示了随着时间的推移数据库中条目数量增加的影响。


8

数字将很难找到,因为两者不在同一空间。一般的答案是,当数据集适合单台计算机的工作内存时,Redis的速度提高了10%到30%。一旦超出该数据量,Redis将失败。Mongo的速度会降低,具体取决于负载类型。对于仅插入类型的负载,一个用户最近报告说速度降低了6到7个数量级(10,000到100,000次),但是该报告还承认存在配置问题,这是非常不正常的工作负载。当必须从磁盘读取某些数据时,正常读取的重负载可能会减慢大约10倍的速度。

结论: Redis会更快,但不是很多。


7

这是一篇有关Tornado框架中大约1年历史的会话性能的出色文章。它比较了几种不同的实现,其中包括Redis和MongoDB。本文中的图表指出,在此特定用例中,Redis比MongoDB落后约10%。

Redis带有内置的基准测试,可以分析您所使用的计算机的性能。Redis 的Benchmark Wiki上有大量原始数据。但是您可能需要四处寻找Mongo。像herehere和一些随机的波兰数字(但它为您自己运行一些MongoDB基准测试提供了起点)。

我相信,解决此问题的最佳方法是在您期望的那种情况下自己执行测试。


在使用Redis和MongoDb作为Zend_Cache后端时,Tornado基准测试与我自己的测试非常吻合。MongoDb的更丰富的功能使您可以使用更少的请求,并且多线程设计的可扩展性比非多线程的单个Redis进程要好得多。结论是MongoDb的规模更高。此外,Redis不再支持虚拟内存。
ColinM

3

就我而言,使用MongoDb WriteConcern是性能比较的决定性因素。如今,大多数mongo驱动程序会将默认的WriteConcern设置为ACKNOWLEDGED,这意味着“写入RAM”(Mongo2.6.3-WriteConcern),在这方面,它与大多数写入操作的redis相当。

但是实际情况取决于您的应用程序需求和生产环境设置,您可能需要将此问题更改为WriteConcern.JOURNALED(写入oplog)或WriteConcern.FSYNCED(写入磁盘),甚至写入副本集(备份)如果需要的话。

然后,您可能会开始看到一些性能下降。其他重要因素还包括数据访问模式的优化程度,索引未命中百分比(请参阅mongostat)和索引。


0

我认为所显示基准上的2-3X具有误导性,因为如果您还取决于运行它的硬件-根据我的经验,机器“越坚固”,差距越大(支持Redis)可能是因为基准测试很快达到了内存限制。

至于内存容量-这是部分正确的,因为还有其他解决方法,有(商业)产品可将Redis数据写回磁盘,也有克服内存大小的集群(多分片)解决方案局限性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.