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