协慌网

登录 贡献 社区

Memcached 与 Redis?

我们正在使用带有Redis服务器的 Ruby Web 应用程序进行缓存。有没有必要测试Memcached

什么会给我们更好的表现? Redis 和 Memcached 之间的任何利弊?

需要考虑的要点:

  • 读 / 写速度。
  • 内存使用情况。
  • 磁盘 I / O 转储。
  • 缩放。

答案

摘要(TL; DR)

2017 年 6 月 3 日更新

Redis 比 memcached 更强大,更受欢迎,支持更好。 Memcached 只能完成 Redis 可以做的一小部分事情。即使它们的特征重叠,Redis 也会更好。

对于任何新的东西,请使用 Redis。

Memcached vs Redis:直接比较

这两种工具都是功能强大,快速的内存数据存储,可用作缓存。两者都可以通过缓存数据库结果,HTML 片段或生成可能很昂贵的任何其他内容来帮助加速您的应用程序。

要考虑的要点

当用于相同的事情时,这里是他们如何使用原始问题的 “要点考虑” 进行比较:

  • 读 / 写速度 :两者都非常快。基准测试因工作负载,版本和许多其他因素而异,但通常显示 redis 与 memcached 一样快或几乎一样快。我推荐 redis,但不是因为 memcached 很慢。不是。
  • 内存使用 :Redis 更好。
    • memcached:您指定缓存大小,当您插入项目时,守护程序会快速增长到略大于此大小。除了重新启动 memcached 之外,从来没有真正的方法可以回收任何空间。您的所有密钥都可能已过期,您可以刷新数据库,它仍将使用您配置的完整 RAM 块。
    • redis:设置最大尺寸取决于您。 Redis 将永远不会使用超过它,并将给你回忆不再使用的内存。
    • 我将 100,000~2KB 的随机句子(~200MB)存储到两者中。 Memcached RAM 使用量增长到~ 225MB。 Redis RAM 使用量增长到大约 228MB。冲洗后,redis 下降到~ 29MB,memcached 保持在~ 225MB。它们在存储数据的方式上同样有效,但只有一个能够回收它。
  • 磁盘 I / O 转储 :redis 的明显胜利,因为它默认执行此操作并具有非常可配置的持久性。如果没有第三方工具,Memcached 没有转储到磁盘的机制。
  • 缩放 :在您需要多个实例作为缓存之前,两者都会为您提供大量的空间。 Redis 包含的工具可以帮助您超越,而 memcached 则不会。

memcached 的

Memcached 是一个简单的易失性缓存服务器。它允许您存储键 / 值对,其中值限制为最大 1MB 的字符串。

擅长这一点,但就是这样。您可以通过其密钥以极高的速度访问这些值,通常会使可用网络饱和甚至内存带宽饱和。

当你重新启动 memcached 时,你的数据就消失了。这适用于缓存。你不应该存储重要的东西。

如果您需要高性能或高可用性,则可以使用第三方工具,产品和服务。

Redis 的

Redis 可以完成与 memcached 相同的工作,并且可以做得更好。

Redis 也可以充当缓存 。它也可以存储键 / 值对。在 redis 中,它们甚至可以高达 512MB。

您可以关闭持久性,它也会在重启时丢失您的数据。如果您希望缓存能够在重新启动后继续运行,那么您也可以执行此操作。实际上,这是默认值。

它也非常快,通常受到网络或内存带宽的限制。

如果一个 redis / memcached 实例的性能不足以满足您的工作负载,那么 redis 是明智的选择。 Redis 包括群集支持,并在 “框中” 右侧附带高可用性工具( redis-sentinel )。在过去的几年里,redis 也成为第三方工具的明显领导者。像 Redis Labs,亚马逊等公司提供了许多有用的 redis 工具和服务。 redis 周围的生态系统要大得多。现在,大规模部署的数量可能大于 memcached。

Redis Superset

Redis 不仅仅是一个缓存。它是内存中的数据结构服务器。下面您将快速了解 Redis 可以做的事情,而不仅仅是像 memcached 这样的简单键 / 值缓存。 大多数 redis 的功能都是 memcached 无法做到的。

文档

Redis 比 memcached 更好地记录。虽然这可能是主观的,但它似乎越来越真实。

redis.io是一个非常容易导航的资源。它允许您在浏览器中尝试 redis,甚至可以为文档中的每个命令提供实时交互式示例。

现在,redis 的堆栈溢出结果是 memcached 的 2 倍。谷歌搜索结果的 2 倍。更容易访问更多语言的示例。更积极的发展。更积极的客户开发。这些测量结果可能并不是单独的,但结合起来,它们描绘了一个清晰的画面,即 redis 的支持和文档更新,更新。

坚持

默认情况下,redis 使用称为快照的机制将数据持久保存到磁盘。如果有足够的 RAM 可用,它可以将所有数据写入磁盘,几乎不会降低性能。它几乎是免费的!

在快照模式下,突然崩溃可能会导致少量数据丢失。如果你绝对需要确保没有数据丢失,请不要担心,redis 也支持 AOF(仅附加文件)模式。在此持久性模式下,数据可以在写入时同步到磁盘。这可以降低磁盘写入速度的最大写入吞吐量,但仍然应该非常快。

如果需要,有许多配置选项可以微调持久性,但默认值非常合理。通过这些选项,可以轻松将 redis 设置为存储数据的安全冗余位置。这是一个真正的数据库。

许多数据类型

Memcached 仅限于字符串,但 Redis 是一个可以提供许多不同数据类型的数据结构服务器。它还提供了充分利用这些数据类型所需的命令。

字符串( 命令

简单的文本或二进制值,最大可达 512MB。这是唯一的数据类型 redis 和 memcached 共享,但 memcached 字符串限制为 1MB。

通过提供用于按位运算,位级操作,浮点递增 / 递减支持,范围查询和多键操作的命令,Redis 为您提供了更多利用此数据类型的工具。 Memcached 不支持任何这些。

字符串对各种用例都很有用,这就是为什么 memcached 仅对这种数据类型非常有用。

哈希( 命令

散列有点像键值存储中的键值存储。它们在字符串字段和字符串值之间映射。使用散列的 Field-> value map 比使用常规字符串的 key-> value map 稍微更节省空间。

哈希值可用作命名空间,或者您希望对多个键进行逻辑分组。使用哈希,您可以有效地获取所有成员,将所有成员一起过期,将所有成员一起删除等。非常适用于您需要分组的多个键 / 值对的任何用例。

散列的一个示例使用是用于在应用程序之间存储用户简档。以用户 ID 作为密钥存储的 redis 哈希将允许您根据需要存储关于用户的多个数据位,同时将它们存储在单个密钥下。使用哈希而不是将配置文件序列化为字符串的优点是,您可以让不同的应用程序在用户配置文件中读 / 写不同的字段,而不必担心一个应用程序覆盖其他人所做的更改(如果序列化过时,可能会发生这种情况)数据)。

列表( 命令

Redis 列表是有序的字符串集合。它们经过优化,可以从列表的顶部或底部(也就是左侧或右侧)插入,读取或删除值。

Redis 的提供许多命令为利用列表,包括列表之间弹出命令推 / 弹出的项目,推 /,截断列表,执行范围查询等

列表使持久,原子,队列。这些对于作业队列,日志,缓冲区和许多其他用例非常有用。

集( 命令

集是唯一值的无序集合。它们经过优化,可让您快速检查值是否在集合中,快速添加 / 删除值以及测量与其他集合的重叠。

这些对于访问控制列表,独特的访问者跟踪器以及许多其他内容非常有用。大多数编程语言都有类似的东西(通常称为 Set)。就像那样,只有分发。

Redis 提供了几个管理集的命令 。存在明显的添加,删除和检查集合。因此,不太明显的命令如弹出 / 读取随机项和用于执行与其他集的联合和交叉的命令。

排序集( 命令

排序集也是唯一值的集合。顾名思义,这些是有序的。他们按照分数排序,然后按字典顺序排列。

此数据类型已针对按分数快速查找进行了优化。获得最高,最低或任何范围的值都非常快。

如果您将用户添加到排序集以及他们的高分,您将拥有一个完美的领导者。随着新的高分进入,只需再次以高分将它们添加到该组中,它将重新排序您的排行榜。同样适用于跟踪用户上次访问的时间以及在您的应用程序中处于活动状态的用户。

存储具有相同分数的值会导致按字典顺序排序(按字母顺序排列)。这对于自动完成功能等功能非常有用。

许多有序集合命令类似于集合的命令 ,有时带有额外的分数参数。还包括用于管理分数和按分数查询的命令。

地理

Redis 的具有几个命令用于存储,检索,以及测量的地理数据。这包括半径查询和测量点之间的距离。

技术上,redis 中的地理数据存储在有序集中,因此这不是真正独立的数据类型。它更像是排序集之上的扩展。

位图和 HyperLogLog

与 geo 一样,这些并不是完全独立的数据类型。这些命令允许您将字符串数据视为位图或超级日志。

位图是我在Strings下引用的位级操作符的用途。这种数据类型是 reddit 最近合作艺术项目的基本构建模块: r / Place

HyperLogLog 允许您使用恒定的极小空间来计算几乎无限的唯一值,并具有令人震惊的准确性。仅使用约 16KB 即可有效计算您网站的唯一身份访问者数量,即使该数字为数百万。

交易和原子性

redis 中的命令是原子的,这意味着您可以确保只要将值写入 redis,该值对连接到 redis 的所有客户端都是可见的。没有等待该值传播。从技术上讲,memcached 也是原子的,但是 redis 在 memcached 之外添加了所有这些功能,值得注意的是,所有这些额外的数据类型和功能都是原子的。

虽然与关系数据库中的事务不完全相同,但 redis 还具有使用 “乐观锁定”( WATCH / MULTI / EXEC )的事务

流水线

Redis 提供了一个名为 “ 流水线 ” 的功能。如果您要执行许多 redis 命令,则可以使用流水线操作将它们一次性发送到 redis,而不是一次一个地发送。

通常,当您执行 redis 或 memcached 命令时,每个命令都是一个单独的请求 / 响应周期。使用流水线技术,redis 可以缓冲多个命令并一次执行所有命令,并在单个回复中响应所有命令的所有响应。

这可以让您在批量导入或涉及大量命令的其他操作上实现更高的吞吐量。

发布 / 订阅

Redis 具有专用于pub / sub 功能的 命令 ,允许 redis 充当高速消息广播器。这允许单个客户端将消息发布到连接到通道的许多其他客户端。

Redis 既有 pub / sub,也有几乎任何工具。像RabbitMQ这样的专用消息代理可能在某些方面具有优势,但同一服务器也可以为您的发布 / 订阅工作负载提供持久的持久队列和其他数据结构,Redis 通常被证明是最好和最简单的工具为了工作。

Lua Scripting

你可以想到像 redis 自己的 SQL 或存储过程这样的lua 脚本 。它的数量越来越少,但这种类比大多有效。

也许你想要 redis 执行复杂的计算。也许你不能让你的交易回滚并且需要保证复杂过程的每一步都会以原子方式发生。使用 lua 脚本可以解决这些问题以及更多问题。

整个脚本以原子方式执行,因此如果您可以将逻辑放入 lua 脚本中,则通常可以避免搞乱乐观锁定事务。

缩放

如上所述,redis 包含对群集的内置支持,并与其自己的高可用性工具(称为redis-sentinel )捆绑在一起。

结论

我会毫不犹豫地为任何新项目或者尚未使用 memcached 的现有项目推荐 redc over memcached。

以上可能听起来像我不喜欢 memcached。相反:它是一种强大,简单,稳定,成熟和强化的工具。甚至有一些用例比 redis 快一点。我喜欢 memcached。我认为这对未来的发展没有多大意义。

Redis 做了 memcached 所做的一切,通常更好。 memcached 的任何性能优势都是次要的,并且特定于工作负载。还有一些工作负载,其中 redis 会更快,而 redis 可以执行的工作负载更多,而 memcached 根本无法完成。面对功能上的巨大鸿沟以及这两种工具如此快速和高效的事实,微小的性能差异似乎很小,它们很可能是您需要担心扩展的最后一块基础设施。

memcached 只有一种情况更有意义:memcached 已经被用作缓存。如果您已经使用 memcached 进行缓存,那么请继续使用它,如果它满足您的需求。转移到 redis 可能不值得,如果你打算使用 redis 进行缓存,它可能无法提供足够的好处来值得花时间。如果 memcached 不能满足您的需求,那么您应该转向 redis。无论您是需要扩展到 memcached 还是需要其他功能,都是如此。

如果使用 Redis

  1. 您需要有选择地删除 / 过期缓存中的项目。 (你需要这个)

  2. 您需要能够查询特定类型的键。 EQ。 'blog1:posts:*','blog2:categories:xyz:posts:*'。哦耶!这是非常重要的。使用此选项可以有选择地使某些类型的缓存项无效。您也可以使用它来使片段缓存,页面缓存,给定类型的 AR 对象等无效。

  3. 持久性(你也需要这个,除非你的缓存在每次重启后都必须预热。对于很少改变的对象非常重要)

使用 memcached if

  1. Memcached 让你头疼!
  2. 嗯...... 聚类? MEH。如果你要走那么远,可以使用 Varnish 和 Redis 来缓存片段和 AR 对象。

根据我的经验,我使用 Redis 比 Memcached 有更好的稳定性

Memcached 是多线程和快速的。

Redis 具有很多功能并且非常快,但完全限于一个核心,因为它基于事件循环。

我们两个都用。 Memcached 用于缓存对象,主要是减少数据库的读取负载。 Redis 用于排序集之类的东西,可以方便地汇总时间序列数据。