首页 文章

Memcached与Redis?

提问于
浏览
1203

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

什么会给我们更好的表现? Redis和Memcached之间的任何优缺点?

需要考虑的要点:

  • 读/写速度 .

  • 内存使用情况 .

  • 磁盘I / O转储 .

  • 缩放 .

17 回答

  • 45

    这里没有指出的一个主要区别是Memcache始终有一个内存上限,而Redis默认不是(但可以配置为) . 如果您总是希望在一定时间内存储键/值(并且由于内存不足而永远不会将其删除),那么您希望使用Redis . 当然,你也冒着内存耗尽的风险......

  • 37

    如果我们说redis是(缓存数据结构)的组合而memcached只是一个缓存,那就没有错 .

  • 129

    剩下的最大原因是专业化 .

    Redis可以做很多不同的事情,其中一个副作用是开发人员可能会开始在同一个实例上使用很多不同的功能集 . 如果您正在使用Redis的LRU功能来获取非LRU侧硬数据存储的缓存,则完全可能会耗尽内存 .

    如果您要将专用Redis实例设置为仅用作LRU实例以避免该特定情况,那么使用Redis而不是Memcached实际上没有任何令人信服的理由 .

    如果你需要一个可靠的“永不停机”的LRU缓存... Memcached将符合要求,因为它不可能通过设计耗尽内存而且特殊功能可以防止开发人员试图使它成为可能危及它的东西 . 简单分离关注点 .

  • 13

    好吧,我主要使用我的应用程序,Memcache缓存会话和redis for doctrine / orm查询对象 . 在性能方面,两者几乎相同 .

  • 4

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

    Redis

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

    • 加载100000个值所需的时间= 18328ms

    Memcached

    • 存储100000个值所需的时间= 797ms

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


    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");
    
  • 75

    我有机会在我使用过的缓存代理中同时使用memcached和redis,让我分享一下我在哪里使用了什么和背后相同的原因....

    Redis>

    1)用于通过群集索引缓存内容 . 我有超过十亿个密钥分布在redis集群上,redis响应时间非常少且稳定 .

    2)基本上,它是一个键/值存储,所以在你的应用程序中你有类似的东西,人们可以使用redis打扰很多 .

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

    Memcache>

    1)是的,可以用作缓存的优化内存 . 我使用它来存储缓存内容,访问频率非常高(50次点击/秒),大小小于1 MB .

    2)当我的单个内容大小> 1MB时,我在memcached中只分配了16GB中的2GB .

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

    如果您要求整体体验,Redis非常环保,因为它易于配置,具有稳定可靠的功能,非常灵活 .

    此外,有一个基准测试结果可用于此link,以下是相同的几个高光,

    enter image description here

    enter image description here

    希望这可以帮助!!

  • 7

    测试 . 运行一些简单的基准测试 . 很长一段时间,我认为自己是一个古老的学校犀牛,因为我主要使用memcached并认为Redis是新的孩子 .

    我目前的公司Redis被用作主要缓存 . 当我挖掘一些性能统计数据并开始测试时,Redis在性能方面与MySQL相当或最低 slower .

    Memcached虽然过于简单,却将Redis从水中吹走了 totally . 它扩展得更好:

    • 用于更大的值(板坯尺寸需要更改,但有效)

    • 用于多个并发请求

    此外,memcached驱逐策略在我看来,实现得更好,导致整体平均响应时间更加稳定,同时处理的数据超过缓存可以处理的数据 .

    一些基准测试表明,在我们的案例中,Redis的表现非常糟糕 . 我认为这与许多变量有关:

    您运行Redis的

    • 类型的硬件
      您存储的

    • 种数据类型

    • 获取和设置的数量

    • 你的应用程序是如何并发的

    • 您需要数据结构存储吗?

    就个人而言,我不同意Redis作者对并发和多线程的看法 .

  • 0

    This is too long to be posted as a comment to already accepted answer, so I put it as a separate answer

    还有一点需要考虑的是,您是否希望缓存实例具有硬性内存上限 .

    由于redis是一个具有大量功能的nosql数据库,因此缓存只有一个选项用于它,它根据需要分配内存 - 你放入的对象越多,它使用的内存就越多 . maxmemory 选项不严格执行内存限制使用率 . 当您使用缓存时,密钥被逐出并过期;机会是你的键大小不一样,所以内部内存碎片发生 .

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

    memcached更适合上述场景,因为它以完全不同的方式管理其内存 . memcached分配一大块内存 - 它将需要的一切 - 然后使用自己实现的slab allocator自己管理这个内存 . 此外,当考虑到对象大小完成LRU驱逐时,memcached努力将内部碎片保持在低水平,因为它实际上是uses per-slab LRU algorithm .

    话虽如此,memcached仍然在环境中占据强势地位,其中必须强制执行和/或预测内存使用 . 我们试图在10-15k op / s的工作负载中使用最新的稳定redis(2.8.19)作为基于嵌入式非持久性LRU的memcached替换,它泄漏了内存A LOT;由于同样的原因,相同的工作负载在一天左右的时间内导致亚马逊的ElastiCache redis实例崩溃 .

  • 19

    如果使用Redis

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

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

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

    使用memcached if

    • Memcached让你头疼!

    • 嗯...聚类? MEH . 如果你要走那么远,使用Varnish和Redis来缓存片段和AR对象 .

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

  • 9

    如果你不介意粗略的写作风格,可以从可用性的角度阅读Systoilet博客上的Redis vs Memcached,但在得出关于性能的任何结论之前,一定要在评论中反复阅读 . 有一些方法问题(单线程繁忙循环测试),Redis自从撰写文章以来也做了一些改进 .

    没有基准链接是完整的而不会让事情有点混乱,所以还要查看Dormondo's LiveJournalthe Antirez Weblog处的一些冲突基准 .

    编辑 - 正如Antirez所指出的那样,Systoilet分析是相当错误的 . 即使超出单线程不足,这些基准测试中的大部分性能差异都可归因于客户端库而不是服务器吞吐量 . the Antirez Weblog的基准确实提供了更多的苹果对苹果(同嘴)的比较 .

  • 0

    Redis更好Redis的优点是,

    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是内存中的键值缓存类型系统 .

    • 不支持各种数据类型存储,如列表,设置为redis .

    • 主要的骗局是Memcache没有磁盘持久性 .

  • 2

    如果你对性能感兴趣,Memcached会更快,甚至因为Redis涉及网络(TCP调用) . 内部Memcache也更快 .

    Redis具有更多功能,正如其他答案所提到的那样 .

  • 83

    另一个好处是,可以非常清楚memcache在缓存方案中的行为方式,而redis通常用作持久性数据存储区,尽管它可以配置为像memcached一样行为,即当它达到最大值时驱逐最近最少使用的项目容量 .

    我曾经使用的一些应用程序只是为了明确我们打算如何处理数据 - 在memcache中,我们编写代码来处理不存在的情况 - redis中的东西,我们依赖它在那里 .

    除此之外,Redis通常被认为是大多数用例的优势,它更具功能,因此更具灵活性 .

  • 7

    摘要(TL; DR)

    Updated June 3rd, 2017

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

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

    Memcached vs Redis:直接比较

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

    要考虑的要点

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

    • Read/write speed :两者都非常快 . 基准测试因工作负载,版本和许多其他因素而异,但通常显示redis与memcached一样快或几乎一样快 . 我推荐redis,但不是因为memcached很慢 . 不是 .

    • Memory usage :Redis更好 .

    • memcached:指定缓存大小,当您插入项目时,守护程序会快速增长到略大于此大小 . 除了重新启动memcached之外,从来没有真正的方法可以回收任何空间 . 您的所有密钥都可以过期,您可以刷新数据库,它仍然会使用您配置的完整RAM块 .

    • redis:设置最大尺寸取决于您 . Redis永远不会使用超过它的功能,并且会为您提供不再使用的内存 .

    • 我将100,000~2KB的随机句子(~200MB)存储到两者中 . Memcached RAM使用量增长到~225MB . Redis RAM使用量增长到大约228MB . 冲洗后,redis下降到~29MB,memcached保持在~225MB . 它们在存储数据的方式上同样有效,但只有一个能够回收它 .

    • Disk I/O dumping :redis的明显胜利,因为它默认执行此操作并且具有非常可配置的持久性 . 如果没有第三方工具,Memcached没有转储到磁盘的机制 .

    • Scaling :在您需要多个实例作为缓存之前,两者都会为您提供大量的空间 . Redis包含的工具可以帮助您超越,而memcached则不会 .

    memcached

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

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

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

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

    redis

    Redis可以执行与memcached相同的工作,并且可以更好地完成它们 .

    Redis也可以act as a cache . 它也可以存储键/值对 . 在redis中,它们甚至可以高达512MB .

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

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

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

    Redis Superset

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

    文档

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

    redis.io是一个非常容易导航的资源 . 它可以让你try redis in the browser甚至为你提供文档中每个命令的实时交互式示例 .

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

    持久性

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

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

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

    许多数据类型

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

    字符串(命令)

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

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

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

    哈希(命令)

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

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

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

    列表(命令)

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

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

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

    集(命令)

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

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

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

    排序集(命令)

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

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

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

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

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

    地理

    Redis有几个commands用于存储,检索和测量地理数据 . 这包括半径查询和测量点之间的距离 .

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

    Bitmap和HyperLogLog

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

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

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

    交易和原子性

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

    虽然与关系数据库中的事务不完全相同,但redis的transactions也使用"optimistic locking"(WATCH / MULTI / EXEC) .

    流水线

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

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

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

    Pub / Sub

    Redis将commands专用于pub/sub functionality,允许redis充当高速消息广播器 . 这允许单个客户端将消息发布到连接到通道的许多其他客户端 .

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

    Lua脚本

    你可以想到lua scripts就像redis 's own SQL or stored procedures. It'一样,但是这个比喻大多数都有效 .

    也许你想要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还是需要其他功能,都是如此 .

  • 1741

    Memcached很擅长做一个简单的键/值存储,并擅长做key => STRING . 这使得它非常适合会话存储 .

    Redis擅长做key => SOME_OBJECT .

    这真的取决于你将要放在那里 . 我的理解是,就性能而言,它们非常均匀 .

    如果您确实找到了一些亲切的发送方式,也可以找到任何客观的基准测试 .

  • 5

    Memcached是多线程和快速的 .

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

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

  • 12

    我们认为Redis是我们工作项目的负载起飞 . 我们认为通过在nginx中使用一个名为HttpRedis2Module的模块或者类似的东西我们会有很棒的速度,但是当我们用AB测试进行测试时我们已经证明了错误 .

    也许模块很糟糕或我们的布局,但这是一个非常简单的任务,用PHP获取数据然后将其填充到MongoDB中甚至更快 . 我们使用APC作为缓存系统,使用php和MongoDB . 它比nginx Redis模块快得多 .

    我的建议是自己测试一下,这样做会告诉你环境的结果 . 我们决定在我们的项目中使用Redis是没有必要的,因为它没有任何意义 .

相关问题