如果 redis 已经是堆栈的一部分,为啥 Memcached 仍然与 Redis 一起使用?

Posted

技术标签:

【中文标题】如果 redis 已经是堆栈的一部分,为啥 Memcached 仍然与 Redis 一起使用?【英文标题】:If redis is already a part of the stack, why is Memcached still used alongside Redis?如果 redis 已经是堆栈的一部分,为什么 Memcached 仍然与 Redis 一起使用? 【发布时间】:2014-06-29 09:04:40 【问题描述】:

Redis 可以完成 Memcached 提供的所有工作(LRU 缓存、项目过期以及现在在 3.x+ 版本中的集群,目前处于测试阶段)或通过 twemproxy 等工具。表现也差不多。此外,Redis 增加了持久性,因此您无需在服务器重启时进行缓存预热。

参考一些比较 Redis 和 Memcache 的旧答案,其中一些支持 Redis 作为 Memcache 的替代品(如果堆栈中已经存在):

Memcached vs. Redis?

Is memcached a dinosaur in comparison to Redis?

Redis and Memcache or just Redis?

尽管如此,在研究大量大型网络公司(如 Instagram、Pinterest、Twitter 等)时,我发现他们将 Memcached 和 Redis 用于不同的目的,而不是使用 Redis 进行主要缓存。主缓存仍然是 Memcached,Redis 用于其基于数据结构的逻辑缓存。

截至 2014 年,当您已经拥有一个 Redis 组件可以完成 memcached 可以做的所有事情时,为什么仍然值得将 memcached 作为附加组件添加到您的堆栈中?除了现有的 Redis 之外,架构师/工程师仍然包含 memcached 的有利点是什么?

更新:

对于我们的平台,我们完全抛弃了 Memcached,并使用 redis 来满足普通和逻辑缓存的需求。高度 高性能、灵活和可靠。

一些示例场景:

按特定模式列出所有缓存的键,并读取或删除它们的值。在 redis 中非常简单,在 memcached 中不可行(容易)。 存储超过 1mb 的有效负载(在 redis 中很容易做到)需要在 memcached 中调整slab 大小,这本身就有性能副作用。 当前缓存内容的简单快照 Redis 集群与语言驱动程序一起已准备好生产,因此集群部署也很容易。

【问题讨论】:

【参考方案1】:

习惯很难改掉 :)

说真的,据我了解,仍然使用 Memcached 的主要原因有两个:

    传统 - 熟悉 Memcached 以及支持它的应用程序的开发人员。这也意味着它是一项成熟且经过充分测试的技术。 可扩展性 - 标准 Memcached 可轻松进行水平扩展,而 Redis(直到并不包括即将发布的 v3)为此需要更多工作(即分片)。

但是:

    回复。遗留 - 鉴于 Redis 的稳健性(数据结构、命令、持久性......),它正在积极开发中,并且客户端使用各种可以想象的语言 - 通常使用它开发新的应用程序。 重新缩放 - 除了即将推出的 v3 之外,还有一些解决方案可以使缩放变得更加容易。例如,Redis Cloud 提供无缝扩展,不会丢失数据或服务中断。另一种流行的 Redis 缩放/分片方法是twemproxy。

【讨论】:

请注意:正如当前维护者在 Twitter 上确认的那样,Memcached 仍在积极开发/维护中。我猜它不经常添加新东西的事实是由于项目已经成熟并且不愿意添加新东西,所以新的开发集中在优化/修复上。 直到 Memcached 还活着并且在踢 - 编辑了我的答案 /ty antirez & dormando 一致散列仍然是一个比纯缓存场景的 Redis 分片更健壮的优雅故障模型。随着节点下降,缓存键会自动移动到其他服务器。只要您有单个服务器,您的缓存仍然可以运行,而不是 redis,如果您失去任何哈希组的主服务器和从服务器,您的集群就会失败。 RedisLabs 非常棒。这是 Userify Cloud 背后的一项关键技术。 我也非常怀疑任何不是基于多线程和事件循环的实现。 ... 好的,现在所有的表演道歉者在哪里,我已经安排了他们的晚餐。现在 redis 可以做到这一点,而且我会从系统方面更加支持 redis。不过,在这一点上,除非开发组非常擅长缓存,否则 memcached 是一个简单且更高效的实现......功能永远不会免费,不要让辩护者告诉你它们是免费的,或者你的成本微不足道。 【参考方案2】:

我今天看到的 memcached over Redis 用例的主要原因是您应该能够通过 plain html 片段缓存(或类似应用程序)获得卓越的内存效率。如果您需要将对象的不同字段存储在不同的 memcached 键中,那么 Redis 哈希将更节省内存,但是当您有大量键 -> simple_string 对时,memcached 应该能够为您提供更多的项目兆字节。

关于 memcached 的其他优点:

这是一段非常简单的代码,所以如果您只需要它提供的功能,我想这是一个合理的替代方案,但我从未在生产中使用过它。 它是多线程的,因此如果您需要在单机设置中进行扩展,这是一件好事,您只需要与一个实例对话。

我相信,随着人们转向智能缓存,或者当他们尝试通过 Redis 数据结构保留缓存数据的结构时,Redis 作为缓存变得越来越有意义。

Redis LRU 和 memcached LRU 的比较。

memcached 和 Redis 都不会执行真正的 LRU 驱逐,而只是一个近似值。

Memcache eviction 是 per-size 类,取决于其slab 分配器的实现细节。例如,如果你想添加一个适合给定大小类的项目,memcached 将尝试删除该类中过期/最近未使用的项目,而不是尝试全局尝试了解对象是什么,而不管它的大小,这是最好的候选。

当达到maxmemory 限制时,Redis 会尝试选择一个好的对象作为驱逐的候选对象,查看所有对象,无论大小等级如何,但只能提供近似好的对象,而不是最好的对象具有更长的空闲时间。

Redis 执行此操作的方式是对一些对象进行采样,从中挑选出空闲(未访问)时间最长的对象。由于 Redis 3.0(目前处于测试阶段),算法得到了改进,并且在驱逐中也采用了一个很好的候选池,所以近似值得到了改进。在Redis documentation you can find a description and graphs with details about how it works.

为什么 memcached 对于简单字符串比 Redis 具有更好的内存占用 -> 字符串映射。

Redis 是一个更复杂的软件,因此 Redis 中的值以更类似于高级编程语言中的对象的方式存储:它们具有关联的类型、编码、用于内存管理的引用计数。这使得 Redis 内部结构良好且易于管理,但与仅处理字符串的 memcached 相比具有开销。

当 Redis 开始提高内存效率时

Redis 能够以一种特殊的内存节省方式存储小型聚合数据类型。例如,表示一个对象的小型 Redis Hash,内部存储不是使用哈希表,而是作为二进制唯一 blob。因此,将每个对象的多个字段设置为哈希比将 N 个单独的键存储到 memcached 中更有效。

实际上,您可以将对象作为单个 JSON(或二进制编码)blob 存储到 memcached 中,但与 Redis 相反,这不允许您获取或更新独立字段。

Redis 在智能缓存方面的优势。

由于 Redis 数据结构,与 memcached 一起使用的通常模式是在缓存失效时销毁对象,以便稍后从数据库中重新创建它,这是使用 Redis 的原始方式。

例如,假设您需要缓存发布到 Hacker News 的最新 N 条新闻,以便填充网站的“最新”部分。你对 Redis 所做的就是获取一个插入最新消息的列表(上限为 M 项)。如果您使用另一个存储来存储您的数据,并将 Redis 作为缓存,那么您所做的就是在发布新项目时填充 both 视图(Redis 和 DB)。没有缓存失效。

但是,应用程序始终可以有逻辑,以便如果发现 Redis 列表为空,例如在启动后,可以从数据库重新创建初始视图。

通过使用智能缓存,与 memcached 相比,Redis 可以以更有效的方式执行缓存,但并非所有问题都适合这种模式。例如,HTML 片段缓存可能不会从这种技术中受益。

【讨论】:

感谢 Antirez 的创造者。但是**为什么纯字符串的 Redis 内存占用比 memcached 多? ** 压缩是一个因素吗?或者当使用 SET 存储纯字符串时,Redis 会存储一些其他额外的数据?如果您可以在答案中包含此信息,那就太好了。 我试图改进回复。感谢您的反馈。 上述“智能”的另一个方面,或者通过操作和/或脚本利用 Redis 的数据类型和服务器端逻辑,是您既可以节省应用程序的复杂性,也可以节省网络(正如@antirez 在antirez.com/news/73 和 Yiftach 在redislabs.com/blog/the-proven-redis-performance 讨论的那样)。 Antirez 感谢您的回答。另一个原因可能是 memcached 稍微快一点。也是旧软件,许多框架默认支持它 很好的答案,一定要喜欢 Redis 之父对社区的奉献精神。

以上是关于如果 redis 已经是堆栈的一部分,为啥 Memcached 仍然与 Redis 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

当我们已经拥有更强大的向量时,为啥还需要堆栈?

为啥Android中的文件'/sys/power/state'总是'mem'?

为啥有的时候开机,redis没有自动起来

当堆栈仍然有元素时,为啥会跳过“如果堆栈不为空”条件?

为啥粉碎后没有立即出现“检测到堆栈粉碎”?

为啥 mmap /dev/mem 返回不同的地址?