我们正在使用带有Redis服务器的Ruby web应用程序进行缓存。是否需要测试Memcached?
什么能给我们更好的表现?Redis和Memcached有什么优缺点吗?
需要考虑的要点:
读/写速度。内存使用情况。磁盘I/O转储。缩放比例。
我们正在使用带有Redis服务器的Ruby web应用程序进行缓存。是否需要测试Memcached?
什么能给我们更好的表现?Redis和Memcached有什么优缺点吗?
需要考虑的要点:
读/写速度。内存使用情况。磁盘I/O转储。缩放比例。
当前回答
剩下的最大原因是专业化。
Redis可以做很多不同的事情,其中一个副作用是开发人员可能会在同一个实例上使用很多不同的功能集。如果您将Redis的LRU功能用于非LRU的缓存,则完全有可能耗尽内存。
如果您打算设置一个专用的Redis实例,仅作为LRU实例使用,以避免出现这种情况,那么在Memcached上使用Redis并没有什么令人信服的理由。
如果您需要可靠的“永不停机”LRU缓存。。。Memcached将符合这一要求,因为它不可能在设计上耗尽内存,而且专用功能阻止开发人员尝试将其制作成可能危及内存的东西。简单的关注点分离。
其他回答
另一个好处是,memcache在缓存场景中的行为非常清楚,而redis通常用作持久数据存储,尽管它可以被配置为在达到最大容量时像memcached一样,即驱逐最近最少使用的项目。
我研究过的一些应用程序同时使用这两种方法,只是为了明确数据的行为方式-内存缓存中的数据,我们编写代码来处理数据不存在的情况-redis中的数据。
除此之外,Redis通常被视为优势,因为它的功能更丰富,因此更灵活。
摘要(TL;DR)
2017年6月3日更新
与memcached相比,Redis更强大、更流行、更受支持。Memcached只能做Redis所能做的一小部分。即使在功能重叠的地方,Redis也更好。
对于任何新功能,请使用Redis。
Memcached与Redis:直接比较
这两种工具都是强大、快速的内存数据存储,可用作缓存。两者都可以通过缓存数据库结果、HTML片段或其他生成成本可能较高的内容来帮助加快应用程序的速度。
需要考虑的要点
当用于相同的事情时,以下是他们如何使用原始问题的“考虑要点”进行比较:
读/写速度:两者都非常快。基准测试因工作负载、版本和许多其他因素而异,但通常显示redis与memcached一样快或几乎一样快。我推荐redis,但不是因为memcached太慢。事实并非如此。内存使用:Redis更好。memcached:指定缓存大小,当插入项目时,守护进程会快速增长到稍大于此大小。除了重新启动memcached之外,从来没有真正的方法来回收这些空间。您的所有密钥都可能过期,您可以刷新数据库,但它仍将使用您配置的全部RAM。redis:设置最大大小取决于您。Redis永远不会使用超过它必须使用的内存,并且会将它不再使用的内存还给你。我将100000到2KB(200MB)的随机句子串存储到两者中。Memcached RAM使用量增长至约225MB。Redis RAM使用量增长至约228MB。在刷新这两项后,redis降至约29MB,memcached保持在约225MB。它们在如何存储数据方面同样高效,但只有一个能够回收数据。磁盘I/O转储:redis是一个明显的胜利,因为它在默认情况下这样做,并且具有非常可配置的持久性。Memcached没有在没有第三方工具的情况下转储到磁盘的机制。缩放:在您需要一个以上的实例作为缓存之前,这两者都会给您大量的空间。Redis包括一些工具,可以帮助您超越这一点,而memcached没有。
内存缓存的
Memcached是一个简单的易失性缓存服务器。它允许您存储键/值对,其中值限制为最大1MB的字符串。
它很擅长这一点,但仅此而已。您可以通过密钥以极高的速度访问这些值,通常会使可用网络甚至内存带宽饱和。
重新启动memcached时,数据将消失。这对于缓存来说很好。你不应该把重要的东西放在那里。
如果您需要高性能或高可用性,可以使用第三方工具、产品和服务。
再贴现率
Redis可以做与memcached相同的工作,并且可以做得更好。
Redis也可以充当缓存。它还可以存储键/值对。在redis中,它们甚至可以达到512MB。
您可以关闭持久性,它也会在重新启动时丢失数据。如果您希望缓存能够在重启后继续运行,那么也可以这样做。事实上,这是默认设置。
它也非常快,通常受到网络或内存带宽的限制。
如果redis/memcached的一个实例对于您的工作负载性能不够,那么redis是一个明确的选择。Redis包括集群支持,并提供了“开箱即用”的高可用性工具(redissentinel)。在过去几年中,redis也成为第三方工具领域的明显领导者。像Redis Labs、Amazon等公司提供了许多有用的Redis工具和服务。redis周围的生态系统要大得多。现在,大规模部署的数量可能大于memcached。
Redis超级集
Redis不仅仅是一个缓存。它是一个内存数据结构服务器。下面,您将快速了解Redis除了作为简单的键/值缓存(如memcached)之外所能做的事情。redis的大部分功能都是memcached无法做到的。
文档
Redis比memcached有更好的文档记录。虽然这可能是主观的,但似乎越来越真实。
redis.io是一个非常容易导航的资源。它允许您在浏览器中尝试redis,甚至为您提供文档中每个命令的实时交互示例。
现在redis的堆栈流结果是memcached的两倍。谷歌搜索结果的两倍。更多语言的更容易访问的示例。更积极的发展。更积极的客户开发。这些度量值可能单独意义不大,但结合起来,它们描绘了一幅清晰的图景,即redis的支持和文档更为丰富,更为最新。
坚持不懈
默认情况下,redis使用名为快照的机制将数据保存到磁盘。如果您有足够的可用RAM,它可以将所有数据写入磁盘,而几乎不会降低性能。几乎是免费的!
在快照模式下,突然崩溃可能会导致少量数据丢失。如果您绝对需要确保没有数据丢失,不要担心,redis也支持AOF(仅附加文件)模式。在这种持久模式下,数据可以在写入时同步到磁盘。这可以将最大写入吞吐量降低到磁盘可以写入的速度,但仍应相当快。
如果需要,有许多配置选项可以微调持久性,但默认值非常合理。这些选项使将redis设置为一个安全、冗余的存储数据的地方变得容易。这是一个真正的数据库。
许多数据类型
Memcached仅限于字符串,但Redis是一个数据结构服务器,可以提供多种不同的数据类型。它还提供了充分利用这些数据类型所需的命令。
字符串(命令)
大小可达512MB的简单文本或二进制值。这是唯一的数据类型redis和memcached共享,尽管memcached字符串限制为1MB。
Redis通过提供按位操作、位级操作、浮点递增/递减支持、范围查询和多键操作的命令,为您提供了更多利用这种数据类型的工具。Memcached不支持这些。
字符串对于所有类型的用例都很有用,这就是memcached单独使用这种数据类型非常有用的原因。
哈希(命令)
哈希有点像键值存储中的键值存储。它们映射字符串字段和字符串值。使用哈希的字段->值映射比使用常规字符串的键->值映射稍微节省空间。
哈希作为名称空间很有用,或者当您希望对多个键进行逻辑分组时。使用哈希,您可以有效地获取所有成员,一起过期所有成员,同时删除所有成员,等等。非常适合需要分组的多个键/值对的任何用例。
哈希的一个示例用途是在应用程序之间存储用户配置文件。以用户ID作为密钥存储的redis哈希将允许您根据需要存储关于用户的数据,同时将其存储在单个密钥下。使用哈希而不是将配置文件序列化为字符串的优点是,您可以让不同的应用程序读取/写入用户配置文件中的不同字段,而不必担心一个应用程序会覆盖其他应用程序所做的更改(如果您序列化了过时的数据,则会发生这种情况)。
列表(命令)
Redis列表是字符串的有序集合。它们针对从列表的顶部或底部(即:左侧或右侧)插入、读取或删除值进行了优化。
Redis提供了许多用于利用列表的命令,包括推送/弹出项目、在列表之间推送/打开、截断列表、执行范围查询等命令。
列表使队列变得非常持久、原子化。这些功能适用于作业队列、日志、缓冲区和许多其他用例。
集合(命令)
集合是唯一值的无序集合。它们经过优化,可以让您快速检查集合中是否有值,快速添加/删除值,并测量与其他集合的重叠。
这些功能非常适合访问控制列表、独特的访客跟踪器以及其他许多功能。大多数编程语言都有类似的东西(通常称为Set)。这是这样的,只是分布的。
Redis提供了几个管理集合的命令。存在明显的添加、删除和检查集合。还有一些不太明显的命令,比如弹出/读取随机项,以及执行与其他集合的并集和交集的命令。
排序集(命令)
排序集也是唯一值的集合。顾名思义,这些是有序的。它们按分数排序,然后按词典排序。
此数据类型经过优化,可按分数快速查找。获得最高值、最低值或其间的任何范围的值都非常快。
如果你将用户与他们的高分一起添加到一个排序的集合中,你就拥有了一个完美的领导委员会。当新的高分出现时,只需将他们的高分再次添加到集合中,它将重新排列您的领导板。此外,还可以跟踪用户上次访问的时间以及谁在您的应用程序中处于活动状态。
存储具有相同分数的值会使它们按字典顺序排列(按字母顺序排列)。这对于自动完成功能之类的事情很有用。
许多已排序的集合命令与集合命令类似,有时还带有一个额外的分数参数。还包括用于管理分数和按分数查询的命令。
Geo
Redis有几个用于存储、检索和测量地理数据的命令。这包括半径查询和测量点之间的距离。
从技术上讲,redis中的地理数据存储在已排序的集合中,因此这不是一个真正独立的数据类型。它更像是排序集之上的扩展。
位图和HyperLogLog
与geo一样,这些数据类型也不是完全独立的。这些命令允许您将字符串数据视为位图或超日志。
位图是我在“字符串”下引用的位级运算符的用途。这个数据类型是reddit最近的合作艺术项目r/Place的基本构建块。
HyperLogLog允许您使用恒定的极小空间,以惊人的精度计算几乎无限的唯一值。仅使用约16KB,您就可以有效地计算网站的唯一访问者数量,即使这个数字是数百万。
事务和原子性
redis中的命令是原子的,这意味着您可以确保在向redis写入值后,所有连接到redis的客户端都可以看到该值。无需等待该值传播。从技术上讲,memcached也是原子的,但redis在memcached之外添加了所有这些功能,值得注意的是,所有这些额外的数据类型和特性也是原子的。
虽然redis与关系数据库中的事务不完全相同,但它也有使用“乐观锁定”(WATCH/MULTI/EXEC)的事务。
管道工程
Redis提供了一个叫做“流水线”的功能。如果要执行许多redis命令,可以使用管道将它们一次发送到redis,而不是一次发送一个。
通常,当您对redis或memcached执行命令时,每个命令都是一个单独的请求/响应周期。通过流水线,redis可以缓冲几个命令并同时执行它们,在一个回复中响应所有命令的所有响应。
这可以让您在批量导入或其他涉及大量命令的操作上实现更大的吞吐量。
发布/订阅
Redis有专门用于发布/订阅功能的命令,允许Redis充当高速消息广播器。这允许单个客户端向连接到频道的许多其他客户端发布消息。
Redis和几乎任何工具一样可以发布/订阅。像RabbitMQ这样的专用消息代理可能在某些领域具有优势,但事实上,同一台服务器也可以为您提供持久的持久队列和发布/订阅工作负载可能需要的其他数据结构,Redis通常会被证明是这项工作的最佳和最简单的工具。
Lua脚本
你可以把lua脚本想象成redis自己的SQL或存储过程。这两者都比这多一点,也少一点,但这种类比基本上是有效的。
也许您需要redis执行复杂的计算。也许您无法让事务回滚,并且需要保证复杂流程的每一步都会自动发生。这些问题以及更多问题可以通过lua脚本来解决。
整个脚本都是以原子方式执行的,因此如果您能够将逻辑融入到lua脚本中,通常可以避免干扰乐观锁定事务。
缩放比例
如上所述,redis包含对集群的内置支持,并与自己的高可用性工具redissentinel捆绑在一起。
结论
我会毫不犹豫地为任何新项目或尚未使用memcached的现有项目推荐redis over memcached。
以上内容听起来好像我不喜欢memcached。相反,它是一种强大、简单、稳定、成熟和硬化的工具。甚至在一些用例中,它比redis稍快。我喜欢memcached。我只是觉得这对未来的发展没有多大意义。
Redis可以做memcached所做的一切,通常做得更好。memcached的任何性能优势都是次要的,而且是特定于工作负载的。还有redis将更快的工作负载,redis可以完成的工作负载更多,而memcached根本无法完成。面对巨大的功能鸿沟,以及这两种工具都非常快速高效的事实,这些微小的性能差异似乎很小,它们很可能是您的基础设施中最不需要担心扩展的部分。
只有一种情况下memcached更有意义:memcached已经用作缓存。如果您已经在使用memcached进行缓存,那么如果它满足您的需要,请继续使用它。转移到redis可能不值得,如果您打算仅使用redis进行缓存,它可能不会提供足够的好处,值得您花费时间。如果memcached不能满足您的需求,那么您可能应该转移到redis。无论您需要扩展到memcached之外,还是需要其他功能,这都是正确的。
如果你不介意粗鲁的写作风格,从可用性的角度来看,Systoilet博客上的Redis vs Memcached值得一读,但在对性能做出任何结论之前,一定要反复阅读评论;存在一些方法上的问题(单线程忙循环测试),自本文撰写以来,Redis也做了一些改进。
没有一个基准链接是完整的,不会有点混淆,所以也可以在Dormondo的LiveJournal和Antirez Weblog上查看一些冲突的基准。
编辑——正如Antirez所指出的,Systoilet分析是相当不合理的。即使在单线程不足的情况下,这些基准测试中的大部分性能差异也可以归因于客户端库,而不是服务器吞吐量。Antirez Weblog上的基准的确提供了更多的苹果对苹果(同一张嘴)的比较。
我们认为Redis是我们工作项目的一个负载起飞点。我们认为通过在nginx中使用一个名为HttpRedis2Module的模块或类似的模块,我们会有惊人的速度,但当使用AB测试进行测试时,我们被证明是错误的。
也许是模块坏了,或者是我们的布局,但这是一个非常简单的任务,用php获取数据然后将其填充到MongoDB中甚至更快。我们使用APC作为缓存系统,并使用php和MongoDB。它比nginxRedis模块快得多。
我的建议是自己测试它,这样做会向您展示环境的结果。我们决定在我们的项目中使用Redis是不必要的,因为它没有任何意义。
Memcached是多线程和快速的。
Redis有很多功能,而且速度非常快,但完全限于一个内核,因为它基于一个事件循环。
我们两者都使用。Memcached用于缓存对象,主要减少数据库的读取负载。Redis用于诸如排序集之类的东西,这对于汇总时间序列数据非常方便。