关于缓存:Memcached与Redis?

Memcached vs. Redis?

我们使用Ruby Web应用程序和Redis服务器进行缓存。是否有测试memcached的点?

什么能让我们有更好的表现?redis和memcached有什么利弊吗?

需要考虑的要点:

    百万千克1读/写速度。
  • 内存使用。百万千克1百万千克1磁盘I/O转储。百万千克1百万千克1缩放比例。百万千克1


摘要(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的字符串。好的。

它很擅长这个,但这就是它所做的一切。您可以以极高的速度访问这些值,通常饱和可用网络,甚至内存带宽。好的。

重新启动MycCurk时,数据就不见了。这对于缓存来说是很好的。你不应该把重要的东西存放在那里。好的。

如果您需要高性能或高可用性,则有第三方工具、产品和服务可用。好的。雷迪斯

redis可以像memcached一样做同样的工作,并且可以做得更好。好的。

Redis也可以用作缓存。它也可以存储键/值对。在Redis中,它们甚至可以达到512MB。好的。

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

它太快了,经常受到网络或内存带宽的限制。好的。

如果Reims/MeMcCurrH的一个实例对您的工作负载不足,则ReDIS是显而易见的选择。ReDIS包括集群支持,并配备了高可用性工具(RADIS Stand)。在过去的几年里,ReDIS也成为第三方工具中的佼佼者。像ReISIS实验室、Amazon等公司提供了许多有用的ReDIS工具和服务。雷迪斯附近的生态系统要大得多。大规模部署的数量现在可能比MycCurp大。好的。Redis超集

redis不仅仅是缓存。它是一个内存数据结构服务器。下面,您将快速了解Redis除了作为一个简单的键/值缓存(如memcached)之外可以做的事情。redis的大部分功能都是memcached无法做到的。好的。文档

redis比memcached有更好的文档记录。虽然这可能是主观的,但似乎越来越真实。好的。

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

现在redis的stackoverflow结果是memcached的两倍。两倍的谷歌搜索结果。更多语言中更容易获取的示例。更积极的发展。更积极的客户开发。这些度量可能不太重要,但结合起来,它们描绘了一幅清晰的画面,即对redis的支持和文档更强大,而且更为最新。好的。坚持不懈

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

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

如果需要的话,有许多配置选项可以微调持久性,但是缺省值是非常合理的。这些选项使Redis易于设置为一个安全、冗余的存储数据的地方。它是一个真正的数据库。好的。许多数据类型

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

大小最多为512MB的简单文本或二进制值。这是唯一的数据类型redis和memcached share,尽管memcached字符串限制为1MB。好的。

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

字符串对于所有类型的用例都很有用,这就是为什么memcached单独使用此数据类型非常有用的原因。好的。哈希(命令)

哈希有点像键值存储中的键值存储。它们在字符串字段和字符串值之间进行映射。使用哈希的field->value映射比使用常规字符串的key->value映射的空间效率稍高。好的。

哈希作为一个名称空间很有用,或者当您想要逻辑地对许多键进行分组时。通过散列,您可以有效地获取所有成员,将所有成员一起过期,将所有成员一起删除,等等。对于需要分组的多个键/值对的任何用例都是很好的选择。好的。

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

redis列表是字符串的有序集合。它们针对从列表的顶部或底部(即:左侧或右侧)插入、读取或删除值进行了优化。好的。

redis提供了许多利用列表的命令,包括推/弹出项的命令、列表之间的推/弹出、截断列表、执行范围查询等。好的。

列表使队列非常持久、原子化。这些对于作业队列、日志、缓冲区和许多其他用例都非常有用。好的。集合(命令)

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

这些对于访问控制列表、独特的访问者跟踪器以及其他很多东西都很有用。大多数编程语言都有类似的东西(通常称为集合)。就像这样,只是分布式的。好的。

Redis提供了多个命令来管理集合。存在诸如添加、删除和检查集合等明显的内容。因此,不太明显的命令,比如弹出/读取随机项,以及执行联合和与其他集合交叉的命令。好的。型排序集(命令)

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

此数据类型针对分数快速查找进行了优化。获取最高、最低或介于两者之间的任何范围的值都是非常快的。好的。型

如果你将用户和他们的高分一起添加到一个分类集合中,你就拥有了一个完美的领导委员会。当新的高分出现时,只要用高分再次把他们加入到集合中,你的领导委员会就会重新排序。还可以跟踪用户上次访问的时间以及在应用程序中处于活动状态的用户。好的。型

用相同的分数存储值会使它们按字典顺序排列(按字母顺序思考)。这对于像自动完成功能这样的事情很有用。好的。型

许多已排序的集合命令与集合命令类似,有时还带有一个额外的分数参数。还包括用于管理分数和按分数查询的命令。好的。型地理位置

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

从技术上讲,redis中的地理数据存储在已排序的集合中,因此这不是真正独立的数据类型。它更像是排序集顶部的扩展。好的。型位图和超级日志

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

位图是我在Strings中引用的位级操作符的作用。此数据类型是Reddit最近的合作艺术项目R/Place的基本构建块。好的。型

HyperlogLog允许您使用一个非常小的常量空间以惊人的精度计算几乎无限的唯一值。仅使用~16kb,您就可以有效地计算站点的唯一访问者数量,即使该数量以百万计。好的。交易与Atomicity

ReDIS中的命令是原子的,这意味着您可以确信,一旦向RADIS写入一个值,该值对于连接到ReDIS的所有客户端都可见。没有等待这个值传播。从技术上讲,MeMcCurk也是原子的,但是ReDIS将所有这些功能添加到MeMcCurm之外,值得注意和令人印象深刻的是,所有这些附加的数据类型和特征也是原子的。好的。

虽然与关系数据库中的事务不完全相同,但Redis也有使用"乐观锁"(watch/multi/exec)的事务。好的。型管道

Redis提供了一个称为"流水线"的功能。如果您有许多要执行的redis命令,可以使用管道将它们一次性发送到redis,而不是一次一个。好的。

通常,当您对redis或memcached执行命令时,每个命令都是一个单独的请求/响应周期。通过管道,redis可以缓冲多个命令并同时执行它们,在一个回复中对所有命令作出响应。好的。

这可以使您在批量导入或涉及大量命令的其他操作上获得更大的吞吐量。好的。发布/订阅

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

Redis可以发布/订阅几乎任何工具。专用消息代理(如rabbitmq)在某些领域可能具有优势,但事实上,同一台服务器还可以为您提供持久耐用的队列和其他可能需要的pub/sub工作负载数据结构,因此redis通常被证明是该工作的最佳和最简单的工具。好的。路标脚本

您可以想到Lua脚本,比如Redis自己的SQL或存储过程。这是或多或少的,但这个类比基本上是可行的。好的。

也许你有复杂的计算,你想重拨执行。也许你负担不起事务回滚,需要保证复杂过程的每一步都会自动发生。这些问题以及更多的问题都可以通过Lua脚本解决。好的。

整个脚本都是原子执行的,因此,如果您可以将逻辑拟合到Lua脚本中,通常可以避免使用乐观锁定事务。好的。缩放比例

如上所述,ReDIS包括内置的集群支持,并结合自己的高可用性工具称为EDCOX1(0)。好的。结论

我毫不犹豫地推荐Redis而不是Memcached用于任何新项目,或现有的尚未使用Memcached的项目。好的。

以上可能听起来我不喜欢memcached。相反:它是一种强大、简单、稳定、成熟、坚硬的工具。甚至有些用例比Redis快一点。我喜欢memcached。我只是觉得这对未来的发展没有多大意义。好的。

redis做memcached做的每一件事,通常更好。memcached的任何性能优势都是次要的,并且是特定于工作负载的。此外,Redis的工作负载也会更快,而且还有更多的工作负载是Memcached无法完成的。在功能上的巨大鸿沟面前,微小的性能差异似乎微不足道,而且这两种工具的速度和效率都非常快,它们很可能是您基础设施的最后一块,您将永远拥有我得担心会有水垢。好的。

只有一种情况下memcached更有意义:memcached已经用作缓存。如果您已经使用memcached进行缓存,那么继续使用它,如果它满足您的需要。转移到Redis的努力可能不值得,而且如果您只打算使用Redis进行缓存,它可能无法提供足够的好处来值得您花费时间。如果memcached不能满足您的需求,那么您可能应该转移到redis。无论您需要扩展到memcached之外还是需要其他功能,这都是正确的。好的。好啊。


使用RIIS IS

  • 需要在缓存中有选择地删除/终止项目。(你需要这个)

  • 您需要查询特定类型的键的能力。公式"blog1:posts:*","blog2:categories:xyz:posts:*"。哦,是的!这很重要。使用此选项可选择性地使某些类型的缓存项失效。您还可以使用它来使片段缓存、页面缓存、只有给定类型的ar对象等失效。

  • 持久性(您也需要这个,除非您对每次重新启动后必须预热的缓存感到满意。对于很少改变的物体非常重要)

  • 使用memcached if

  • memcached让你头疼!
  • 嗯…聚类?无聊的。如果你想走那么远,使用Varnish和Redis来缓存片段和AR对象。
  • 根据我的经验,我对redis的稳定性比memcached要好得多。


    memcached是多线程、快速的。

    Redis有很多特性,速度非常快,但是完全局限于一个核心,因为它基于一个事件循环。

    我们两者都使用。memcached用于缓存对象,主要是减少数据库上的读取负载。redis用于排序集之类的东西,这些集合便于汇总时间序列数据。


    这太长了,无法作为评论发布到已接受的答案,因此我将其作为单独的答案

    还需要考虑的一件事是,您是否希望缓存实例具有硬内存上限。

    由于redis是一个具有大量功能的nosql数据库,缓存只是它可以使用的一个选项,因此它可以根据需要分配内存—您放入的对象越多,它使用的内存就越多。maxmemory选项不严格执行内存上限使用。当您使用缓存时,密钥会被收回并过期;很可能您的密钥大小不完全相同,因此会发生内部内存碎片。

    默认情况下,redis使用jemalloc内存分配器,它尽量做到紧凑和快速,但它是一个通用的内存分配器,它无法跟上大量的分配和高速发生的对象清除。因此,在某些负载模式下,redis进程显然会由于内部碎片而泄漏内存。例如,如果您的服务器有7GB的RAM,并且您希望将redis用作非持久性的lru缓存,您可能会发现随着时间的推移,maxmemory设置为5GB的redis进程将使用越来越多的内存,最终达到总RAM限制,直到内存不足杀手干预。

    memcached更适合上述场景,因为它以完全不同的方式管理内存。memcached分配一大块内存——它将需要的所有东西——然后使用自己实现的slab分配器自己管理这个内存。此外,memcached努力使内部碎片保持在较低的水平,因为它实际上使用了每板的lru算法,在进行lru收回时考虑了对象大小。

    这样说来,MeMCACHE在环境中仍然具有很强的地位,内存使用必须被执行和/或是可预测的。我们尝试使用最新的稳定ReDIS(2.819)作为非持久性基于LRU的MycCask替换在10-15K OP/S工作负载中的一个掉落,它泄露了大量内存;同样的工作量也因为同样的原因在一天左右摧毁了Amazon的弹力ReDISIS实例。


    memcached擅长做一个简单的键/值存储,擅长做键=>字符串。这使得它非常适合会话存储。

    redis擅长做key=>一些对象。

    这真的取决于你要把什么放进去。我的理解是,在性能方面,它们相当均匀。

    也祝你好运,找到任何客观的基准,如果你真的找到一些好心的送他们我的方式。


    如果你不介意粗俗的写作风格,那么从可用性的角度来看,Redis vs Memcached在Systolet博客上是值得一读的,但是在得出任何性能结论之前,一定要阅读评论中的前后内容;存在一些方法学问题(单线程忙环测试),而且Redis自那以后已经有了一些改进。他也写了这篇文章。

    没有一个基准链接是完整的,不会造成一点混乱,所以也可以在Dormondo的LiveJournal和Antirez的weblog上查看一些相互冲突的基准。

    编辑——正如安提雷斯指出的那样,系统分析是一个相当错误的构想。即使在单线程不足的情况下,这些基准中的大部分性能差异也可以归因于客户端库,而不是服务器吞吐量。Antirez网络日志的基准确实提供了更多的苹果对苹果(用同样的嘴)的比较。


    我有机会在我工作过的缓存代理中同时使用memcached和redis,让我分享一下我到底在何处使用了memcached和redis背后的原因……

    雷迪斯>

    1)用于在集群上索引缓存内容。我在Redis集群中拥有超过十亿个密钥,Redis响应时间比较短且稳定。

    2)基本上,它是一个密钥/值存储库,所以在您的应用程序中,如果您有类似的东西,您可以使用Redis来解决很多问题。

    3)Redis持久性、故障转移和备份(AOF)将使您的工作更轻松。

    内存缓存>

    1)是的,可以用作缓存的优化内存。我用它来存储经常访问的缓存内容(每秒命中50次),其大小小于1 MB。

    2)当我的单个内容大小大于1MB时,我只为memcached分配了16GB中的2GB。

    3)当内容接近极限时,我偶尔会在统计数据中观察到更高的响应时间(而不是Redis的情况)。

    如果你要求整体体验,Redis是绿色的,因为它很容易配置,非常灵活,功能稳定可靠。

    此外,在这个链接上有一个基准测试结果,下面是来自相同的一些Highlight,

    enter image description here

    enter image description here

    希望这有帮助!!


    测试。运行一些简单的基准测试。有很长一段时间,我认为自己是一只老派犀牛,因为我用的大部分是memcached,并认为redis是新来的孩子。

    在我目前的公司中,redis被用作主缓存。当我研究了一些性能统计数据并简单地开始测试时,就性能而言,redis比mysql慢得多,或者说比mysql慢得多。

    memcached虽然简单,却把redis完全从水中吹了出来。它的规模更大:

    • 对于较大的值(需要改变板的尺寸,但有效)
    • 对于多个并发请求

    此外,Memcached收回策略在我看来得到了更好的实现,这使得总体上的平均响应时间更稳定,同时处理的数据比缓存可以处理的多。

    一些基准测试显示,在我们的案例中,redis的性能非常差。我认为这与许多变量有关:

    • 运行Redis的硬件类型
    • 存储的数据类型
    • 获取和设置的数量
    • 你的应用程序有多并发
    • 你需要数据结构存储吗

    就个人而言,我不分享Redis作者对并发和多线程的看法。


    另一个好处是,它可以非常清楚Memcache在缓存场景中的行为,而Redis通常用作持久数据存储,尽管它可以配置为在达到最大容量时像Memcached一样,将最近使用过的项目移出。

    我研究过的一些应用程序使用这两种方法只是为了让我们清楚地了解数据的行为方式——在memcache中使用数据,在没有数据的情况下编写代码来处理数据——在redis中使用数据,我们依赖于数据的存在。

    除此之外,Redis通常被认为是优越的,因为大多数用例都具有更丰富的特性,因此更灵活。


    如果我们说ReDIS是(Cache +数据结构)的组合,而MeMcCache只是一个缓存,那就不会错了。


    这里还没有指出的一个主要区别是memcache在任何时候都有一个内存上限,而redis在默认情况下不是(但可以配置为)。如果您总是希望在一定时间内存储一个键/值(并且永远不会因为内存不足而将其取出),那么您希望使用redis。当然,你也会面临内存耗尽的问题…


    针对redis-2.2.2和memcached设置和获取100K唯一键和值的一个非常简单的测试。两者都在LinuxVM(CentOS)上运行,我的客户机代码(粘贴在下面)在Windows桌面上运行。

    雷迪斯

    • 存储100000个值所用的时间=18954ms

    • 加载100000个值所需的时间为=18328毫秒。

    内存缓存

    • 存储100000个值的时间为=797毫秒。

    • 检索100000个值所用的时间=38984ms

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Jedis jed = new Jedis("localhost", 6379);
    int count = 100000;
    long startTime = System.currentTimeMillis();
    for (int i=0; i<count; i++) {
      jed.set("u112-"+i,"v51"+i);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("Time taken to store"+ count +" values is ="+(endTime-startTime)+"ms");

    startTime = System.currentTimeMillis();
    for (int i=0; i<count; i++) {
      client.get("u112-"+i);
    }
    endTime = System.currentTimeMillis();
    System.out.println("Time taken to retrieve"+ count +" values is ="+(endTime-startTime)+"ms");


    最大的遗留原因是专业化。

    Redis可以做很多不同的事情,其中一个副作用是开发人员可能会在同一个实例上开始使用这些不同的特性集。如果您使用redis的lru特性作为缓存,而不是lru,那么完全有可能耗尽内存。

    如果您要设置一个专用的redis实例,只作为一个lru实例使用,以避免出现这种情况,那么在memcached上使用redis实际上没有任何令人信服的理由。

    如果你需要一个可靠的"永不停机"的lru缓存…memcached会满足你的需求,因为它不可能通过设计耗尽内存,而专门的功能阻止开发人员试图使它成为可能危及它的东西。简单的关注分离。


    我们认为redis是我们工作中的项目的一个起飞工具。我们认为,通过在nginx中使用一个名为httpredis2module的模块或类似的模块,我们的速度会非常快,但是当使用ab测试进行测试时,我们被证明是错误的。

    也许模块不好,或者我们的布局不好,但这是一个非常简单的任务,用PHP获取数据并将其放入MongoDB更快。我们使用apc作为缓存系统,使用php和mongodb。它比nginx redis模块快得多。

    我的建议是自己测试它,这样做会向您展示环境的结果。我们认为在我们的项目中使用redis是不必要的,因为它没有任何意义。


    如果您对性能感兴趣,memcached会更快,这是因为redis涉及网络(TCP调用)。此外,内存缓存的内部速度更快。

    Redis有更多的功能,正如其他答案所提到的。


    瑞迪斯更好Redis的优点是,

    1
    2
    3
    4
    1.It has a lot of data storage options such  as  string  , sets , sorted sets ,  hashes ,  bitmaps
    2.Disk Persistence of records
    3.Stored Procedure (LUA acripting)  support
    4.Can act as a Message Broker using PUB/SUB

    而memcache是内存中的键值缓存类型系统。

  • 不支持各种数据类型存储,如列表、集合雷迪斯。
  • 主要的缺点是memcache没有磁盘持久性。

  • 嗯,我主要在我的应用程序中使用,memcache用于缓存会话,redis用于条令/orm查询对象。就性能而言,两者几乎相同。