Memcached与Redis?

时间:2012-05-11 20:52:48

标签: caching web-applications memcached redis

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

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

要考虑的要点:

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

17 个答案:

答案 0 :(得分:133)

如果

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

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

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

  4. 使用memcached if

    1. Memcached让你头疼!
    2. 嗯...聚类? MEH。如果你要走那么远,可以使用Varnish和Redis缓存片段和AR对象。
    3. 根据我的经验,我使用Redis比Memcached具有更好的稳定性

答案 1 :(得分:91)

Memcached是多线程且快速的。

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

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

答案 2 :(得分:86)

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

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

由于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实例崩溃。

答案 3 :(得分:46)

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

Redis擅长做key => SOME_OBJECT。

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

同样祝你好运找到任何客观的基准,如果你确实找到了一些亲切的发送方式。

答案 4 :(得分:37)

如果您不介意粗略的写作风格,Systoilet博客上的Redis vs Memcached值得从可用性的角度阅读,但请务必阅读背面&在对表现作出任何结论之前,在评论中;有一些方法问题(单线程繁忙循环测试),Redis自从撰写文章以来也做了一些改进。

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

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

答案 5 :(得分:22)

我有机会在我使用过的缓存代理中同时使用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

希望这会有所帮助!!

答案 6 :(得分:13)

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

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

除此之外,Redis通常被认为是大多数用例更优越,功能更丰富,更灵活。

答案 7 :(得分:13)

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

我目前的公司Redis被用作主要缓存。当我挖掘一些性能统计数据并开始测试时,就性能而言,Redis与MySQL的可比性或最低更慢

Memcached虽然过于简单,却将Redis从水中吹走完全。它的表现要好得多:

  • 表示较大的值(板坯尺寸需要更改,但有效)
  • 用于多个并发请求

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

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

  • 您在
  • 上运行Redis的硬件类型
  • 您存储的数据类型
  • 获取和设置的数量
  • 你的应用程序是如何并发的
  • 您是否需要数据结构存储

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

答案 8 :(得分:9)

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

答案 9 :(得分:7)

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

答案 10 :(得分:7)

一个非常简单的测试,用于设置和获取针对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");

答案 11 :(得分:5)

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

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

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

答案 12 :(得分:5)

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

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

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

如果你需要一个可靠的&#34;永远不会下降&#34; LRU缓存... Memcached将符合要求,因为它不可能通过设计耗尽内存,而specialize功能可以防止开发人员试图使其成为可能危及它的东西。简单分离关注点。

答案 13 :(得分:3)

即使您对性能感兴趣,Memcached也会更快,即使Redis涉及网络(TCP调用)也是如此。同样,内部Memcache速度更快。

Redis具有其他答案中提到的更多功能。

答案 14 :(得分:2)

Redis更好。

Redis的优点是,

  1. 它有很多数据存储选项,如字符串,集合,有序集,哈希,位图
  2. 记录的磁盘持久性
  3. 存储过程(LUA脚本)支持
  4. 可以使用PUB / SUB
  5. 充当消息代理

    Memcache是内存中键值缓存类型系统。

    1. 不支持各种数据类型存储,例如列表,集合 Redis的。
    2. 主要的骗局是Memcache没有磁盘持久性。

答案 15 :(得分:0)

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

答案 16 :(得分:0)

Here是Amazon提供的很棒的文章/区别

与memcached相比,Redis显然是赢家。

Memcached仅加1 它是多线程的,而且速度很快。 Redis具有很多强大的功能,并且速度很快,但仅限于一个内核。

有关Redis的要点,Memcached不支持这些要点

  • 快照-用户可以对Redis缓存进行快照并保持不变    二级存储的任何时间点。
  • 内置支持许多数据结构,例如Set,Map,SortedSet, 列表,位图等。
  • 在Redis中支持Lua脚本