更新于2017年6月3日
Redis比memcached更加强大、流行和得到更好的支持。Memcached只能做Redis能够完成其中一小部分的事情。即使在两者的功能重叠的地方,Redis也更加优秀。
对于任何新功能,都应该使用Redis。
这两个工具都是快速的、内存中的数据存储器,作为缓存很有用。它们都可以通过缓存数据库结果、HTML片段或其他任何可能难以生成的内容来加速应用程序。
当用于相同的用途时,以下是它们使用原始问题的“需要考虑的要点”的比较:
Memcached是一个简单的易失性缓存服务器。它允许您存储键/值对,其中值被限制为字符串,最多可达1MB。
它擅长于这一点,但这就是它所能做的全部。您可以通过其键极快地访问这些值,通常会饱和可用的网络甚至内存带宽。
当您重新启动memcached时,您的数据将消失。这对于缓存来说很好。您不应该在那里存储任何重要内容。
如果您需要高性能或高可用性,则有第三方工具、产品和服务可用。
Redis可以完成与memcached相同的工作,并且可以做得更好。
Redis也可以作为缓存。它也可以存储键/值对。在redis中,它们甚至可以达到512MB。
您可以关闭持久性,在重新启动时它会愉快地丢失您的数据。如果您希望缓存在重新启动后仍然存在,它也可以让您这样做。事实上,这是默认设置。
它也非常快,通常受网络或内存带宽的限制。
如果一个redis/memcached实例的性能不足以满足您的工作量,那么redis是明显的选择。Redis包括集群支持并配备了高可用性工具(redis-sentinel),这些都在“盒子”中。近年来,redis也成为第三方工具的明显领导者。像Redis Labs,Amazon和其他公司提供了许多有用的redis工具和服务。围绕redis的生态系统更大。现在,大规模部署的数量可能比memcached更多。Redis不仅是缓存。它还是一个内存数据结构服务器。以下是Redis可以执行的一些快速概述,超出了像memcached这样的简单键/值缓存。 Redis的大多数功能是memcached无法完成的。
Redis的文档比memcached更好。虽然这可能是主观的,但它似乎越来越真实。
redis.io 是一个非常好用、易于导航的资源。它可以让您在浏览器中 尝试redis,并且在文档中每个命令都提供了实时交互式示例。
现在,与memcached相比,redis在stackoverflow上的结果是2倍,谷歌搜索结果也是2倍。同时提供更多语言的示例,开发活跃度更高,客户端开发更加活跃。这些指标单独来看可能意义不大,但综合起来,它们清晰地表明redis的支持和文档更加强大和更新。
默认情况下,redis使用一种称为快照机制的方法将您的数据持久化到磁盘上。如果您有足够的RAM可用,它几乎可以在没有性能降级的情况下将所有数据写入磁盘。这几乎是免费的!
在快照模式下,突然崩溃可能导致少量数据丢失。如果您绝对需要确保没有数据丢失,不用担心,redis也有AOF(仅追加文件)模式来支持您。在这种持久性模式下,数据可以在写入时同步到磁盘。这可能会将最大写入吞吐量降低到磁盘写入速度的速度,但应该仍然非常快。Redis提供了更多的工具来利用这种数据类型,通过提供位运算、位级操作、浮点数增量/减量支持、范围查询和多键操作命令。Memcached不支持这些功能。
字符串在各种用例中都很有用,这就是为什么仅使用这种数据类型时,Memcached也相当有用。
哈希有点像一个键值存储中的键值存储。它们将字符串字段与字符串值映射起来。使用哈希的字段->值映射比使用常规字符串的键->值映射稍微更节省空间。
哈希作为命名空间很有用,或者当您想要逻辑上分组许多键时。使用哈希,您可以高效地获取所有成员、一起过期所有成员、一起删除所有成员等。非常适合任何需要分组多个键/值对的用例。
一个哈希表的实例应用是在不同应用之间存储用户资料。使用以用户ID为键值的Redis哈希表可以让您存储任意数量的关于用户的数据,同时将它们存储在单个键下。使用哈希表的好处是,相比将用户资料序列化成字符串,您可以让不同的应用程序读取/写入用户资料中的不同字段,而无需担心其中一个应用程序会覆盖其他应用程序所做的更改(如果您序列化了过期数据,则可能会发生这种情况)。
Redis列表是有序的字符串集合。它们被优化为从列表的顶部或底部(也称为左侧或右侧)插入、读取或删除值。
Redis提供了许多命令来利用列表,包括推送/弹出项目、在列表之间推送/弹出、截断列表、执行范围查询等。
列表非常适合用作持久性、原子性队列。这对于作业队列、日志、缓冲区和许多其他用例非常有效。
集合是无序的唯一值的集合。它们被优化,让你可以快速检查一个值是否在集合中,快速添加/删除值,并测量与其他集合的重叠。
这些非常适用于访问控制列表、独特的访问者跟踪器等许多其他事情。大多数编程语言都有类似的东西(通常称为Set)。这就像那样,只是分布式的。
Redis提供了几个命令来管理集合。显而易见的是添加、删除和检查集合。还有一些不太明显的命令,例如弹出/读取随机项以及与其他集合执行联合和交集的命令。
排序集合也是唯一值的集合。这些,顾名思义,是有序的。它们按得分排序,然后按字典顺序排序。
这种数据类型被优化为通过分数快速查找。获取最高、最低或任何介于其间的一系列值非常快速。
如果您将用户与其高分数一起添加到排序集中,您就拥有了一个完美的排行榜。随着新的高分数的出现,只需再次将它们与其高分数添加到集合中,它就会重新排序您的排行榜。还非常适用于跟踪用户上次访问的时间以及谁在您的应用程序中处于活动状态。像 geo 一样,这些并不是完全独立的数据类型。这些命令允许您将字符串数据视为位图或超级对数。
位图是我在“字符串”下提到的位级运算符所用的数据类型。这种数据类型是 reddit 最近合作艺术项目 r/Place 的基本构建块。
HyperLogLog 允许您使用极小的常量空间计数几乎无限的唯一值,并具有惊人的准确性。只使用 ~16KB,即使访问者数量达到百万级别,您也可以高效地计算出网站的唯一访问者数量。
Redis 中的命令是原子的,这意味着您可以确信,只要您将一个值写入 Redis,该值就对连接到 Redis 的所有客户端可见。没有等待该值传播的时间。从技术上讲,memcached 也是原子的,但是随着 Redis 添加了所有这些功能,超越了 memcached,值得注意的是,所有这些附加的数据类型和功能也是原子的,这相当令人印象深刻。
虽然与关系型数据库中的事务不完全相同,但redis也有transactions,使用“乐观锁定”(WATCH/MULTI/EXEC)。
Redis提供了一个名为“pipelining”的功能。如果您想执行许多redis命令,可以使用管道技术将它们一次性发送到redis,而不是逐个发送。
通常情况下,当您向redis或memcached执行命令时,每个命令都是单独的请求/响应周期。使用管道技术,redis可以缓冲多个命令并同时执行它们,以单个回复响应所有命令的所有响应。
这可以让您在涉及大量命令的批量导入或其他操作中实现更高的吞吐量。
如果您需要有选择地删除/过期缓存中的项目,请使用Redis。(您需要这个)
如果您需要查询特定类型的键,例如“blog1:posts:*”,“blog2:categories:xyz:posts:*”等等。这非常重要。使用此功能可以有选择性地使某些类型的缓存项失效,也可以用于无效化片段缓存、页面缓存、给定类型的AR对象等。
持久化(除非您不介意每次重新启动后都要重新填充缓存,否则您也需要此功能。对于很少更改的对象非常重要)
如果:
根据我的经验,Redis比Memcached更加稳定。
Memcached是多线程且快速的。
Redis具有许多功能且非常快,但完全限制在一个核心上,因为它基于事件循环。
我们同时使用两者。Memcached 用于缓存对象,主要减少数据库的读取负载。Redis 用于像排序集这样的东西,非常适用于汇总时间序列数据。
这段内容太长了,不能作为已接受的答案的评论发布,因此我将其作为单独的答案发布
还有一件事需要考虑,那就是您是否预计在缓存实例上设置硬上限内存。
由于redis是一个nosql数据库,具有大量功能并且缓存只是其中之一,因此它会根据需要分配内存-您放置的对象越多,它使用的内存就越多。 maxmemory
选项不严格强制执行上限内存限制。在使用缓存时,键被逐出和过期;可能您的键大小不同,因此会发生内部内存碎片。
默认情况下,redis使用jemalloc 内存分配器,它尽最大努力既紧凑又快,但它是一种通用的内存分配器,无法跟上高速发生的大量分配和对象清除。由于这个原因,在某些负载模式下,redis进程可能会因内部碎片而泄漏内存。例如,如果您的服务器有7 Gb RAM,并且您希望将redis用作非持久LRU缓存,则可能会发现将maxmemory
设置为5 Gb的redis进程会随着时间的推移而使用越来越多的内存,最终达到总RAM限制,直到内存杀手干预。
memcached更适合上述场景,因为它以完全不同的方式管理内存。 memcached分配一个大内存块-它将永远需要的所有东西-然后自己管理此内存,使用其自己实现的slab分配器。此外,memcached努力保持内部碎片低,因为它实际上使用每个slab的LRU算法,当考虑对象大小时进行LRU逐出。
话虽如此,memcached仍然在需要强制执行和/或可预测内存使用的环境中占据着强势地位。我们尝试将最新稳定版本的redis(2.8.19)作为一种即插即用、非持久性、基于LRU的memcached替代方案,在每秒10-15k次操作的工作负载中进行测试,结果发现它大量泄漏内存;同样的工作负载会因为同样的原因,在一天左右时间内导致亚马逊的ElastiCache redis实例崩溃。
Memcached擅长作为一个简单的键值存储器,并且擅长于处理键值对=>字符串。这使得它非常适合用于会话存储。
Redis则擅长于处理键值对=>某些对象。
实际上,这取决于您将要放入其中的内容。就性能而言,据我了解,它们相当平均。
如果您找到一些客观的基准测试,请祝你好运,如果您找到了,请友情发送给我。
如果您不介意一种粗俗的写作风格,Systoilet博客上的Redis与Memcached的比较从可用性角度来看值得一读,但在得出性能结论之前,请务必阅读评论中的回复,因为存在一些方法论问题(单线程忙循环测试),并且自该文章撰写以来,Redis已经进行了一些改进。
没有混淆事情的基准链接是不完整的,因此还请查看Dormondo的LiveJournal和Antirez Weblog上的一些相互矛盾的基准测试结果。
编辑 -- 正如Antirez指出的那样,Systoilet分析相当不明智。即使超越了单线程缺陷,这些基准测试中许多性能差异都可以归因于客户端库而不是服务器吞吐量。 Antirez Weblog中的基准测试确实呈现了更加公正的比较。
我在实现缓存代理时使用了memcached和redis,让我与您分享我在哪里使用了什么以及背后的原因...
Redis >
1)用于对缓存内容进行索引,跨集群。我有超过十亿个键分布在redis集群中,redis响应时间相当低且稳定。
2)基本上,它是一个键/值存储,所以无论在应用程序的哪个地方您有类似的东西,都可以使用redis。
3)Redis持久性、故障转移和备份(AOF)将使您的工作更轻松。
Memcache >
1)是一种优化的内存,可用作缓存。我用它来存储缓存内容,这些内容非常频繁地被访问(每秒50次),大小小于1 MB。
2)我只分配了16 GB中的2 GB给memcached,而且只有在单个内容大小大于1MB时才这样做。
3)随着内容接近极限,我偶尔会观察到更高的响应时间统计数据(不适用于redis)。
如果你想要整体的经验,Redis比Memcached更好,因为它易于配置,具有稳定的鲁棒特性。
此外,这里有一份基准测试结果,链接在这里,以下是一些亮点,
希望对您有所帮助!
测试。运行一些简单的基准测试。很长一段时间我认为自己是一只老派的犀牛,因为我主要使用memcached,而把Redis看作是新生事物。
在我现任公司中,Redis被用作主要缓存。但当我深入了解了一些性能统计并开始简单测试时,Redis在性能方面与MySQL相比,表现相似或者稍微慢一点。
虽然Memcached过于简单,但完全击败了Redis。它的扩展性要好得多:
此外,我的观点是,Memcached的驱逐策略实现得更好,可以在处理超出缓存容量的数据时,保持平均响应时间的稳定性。
一些基准测试揭示,在我们的情况下,Redis表现非常差。我相信这与许多变量有关:
个人而言,我不认同Redis作者对并发性和多线程的看法。
如果我们说Redis是(缓存+数据结构)的组合,而Memcached只是一种缓存,这并不算错。