我们正在将带Redis服务器的Ruby Web应用程序用于缓存。有没有要测试Memcached的地方呢?
什么会给我们带来更好的性能?Redis和Memcached之间有什么优缺点?
要考虑的要点:
- 读/写速度。
- 内存使用情况。
- 磁盘I / O转储。
- 缩放比例。
我们正在将带Redis服务器的Ruby Web应用程序用于缓存。有没有要测试Memcached的地方呢?
什么会给我们带来更好的性能?Redis和Memcached之间有什么优缺点?
要考虑的要点:
Answers:
2017年6月3日更新
与memcached相比,Redis功能更强大,更受欢迎并且得到更好的支持。Memcached只能做Redis可以做的一小部分。即使Redis的功能重叠,它也更好。
对于任何新内容,请使用Redis。
两种工具都是功能强大,快速的内存中数据存储,可用作缓存。两者都可以通过缓存数据库结果,HTML片段或其他可能产生成本很高的内容来帮助加快应用程序的速度。
当用于同一事物时,以下是它们如何使用原始问题的“要考虑的要点”进行比较:
Memcached是一个简单的易失性缓存服务器。它允许您存储键/值对,其中值限制为最大1MB的字符串。
擅长此事,但仅此而已。您可以通过它们的键以极高的速度访问这些值,这通常会使可用的网络或什至是内存带宽饱和。
重新启动内存缓存后,您的数据不见了。这对于缓存很好。您不应该在其中存储任何重要内容。
如果您需要高性能或高可用性,则可以使用第三方工具,产品和服务。
Redis可以完成与memcached相同的工作,并且可以做得更好。
Redis也可以充当缓存。它也可以存储键/值对。在redis中,它们甚至可以达到512MB。
您可以关闭持久性,并且在重新启动时也很可能会丢失数据。如果您希望缓存能够继续运行,那么重新启动也可以。实际上,这是默认设置。
它也非常快,通常受网络或内存带宽的限制。
如果一个redis / memcached实例的性能不足以满足您的工作负载,那么redis是不二之选。Redis包括集群支持,并附带了“在盒子里”的高可用性工具(redis-sentinel)。在过去的几年中,redis也已成为第三方工具的明确领导者。Redis Labs,Amazon等公司提供许多有用的Redis工具和服务。Redis周围的生态系统更大。现在,大规模部署的数量可能会大于内存缓存的数量。
Redis不仅仅是一个缓存。它是一个内存中的数据结构服务器。在下面,您将快速概述Redis可以做的事情,而不仅仅是像memcached这样的简单键/值缓存。Redis的大多数功能都是memcached无法做到的。
Redis的文档比memcached的文档更好。尽管这可能是主观的,但它似乎一直在越来越真实。
redis.io是一个很棒的易于导航的资源。它使您可以在浏览器中尝试redis,甚至还可以通过文档中的每个命令为您提供实时的交互式示例。
现在,redis的堆栈溢出结果是内存缓存的2倍。是Google结果的2倍。提供更多语言的更易于访问的示例。更积极的发展。更积极的客户开发。这些度量可能并没有太大的意义,但结合起来可以清楚地看到,有关Redis的支持和文档越来越多,而且更新得多。
默认情况下,redis使用称为快照的机制将数据持久保存到磁盘。如果您有足够的可用RAM,则可以将所有数据写入磁盘而几乎不会降低性能。它几乎是免费的!
在快照模式下,突然崩溃可能会导致少量数据丢失。如果您绝对需要确保没有数据丢失,请放心,redis也可以通过AOF(仅附加文件)模式在后台工作。在这种持久模式下,数据可以在写入时同步到磁盘。这样可以将最大写入吞吐量降低到磁盘可以写入的速度,但是仍然应该非常快。
如果需要,有许多配置选项可以微调持久性,但是默认值非常明智。这些选项使将Redis设置为安全,冗余的存储数据位置变得容易。这是一个真实的数据库。
Memcached仅限于字符串,但是Redis是一个数据结构服务器,可以提供许多不同的数据类型。它还提供了充分利用这些数据类型所需的命令。
简单文本或二进制值,最大可为512MB。这是唯一的数据类型redis和memcached共享,尽管memcached字符串限制为1MB。
Redis通过提供用于按位操作,位级别操作,浮点增量/减量支持,范围查询和多键操作的命令,为您提供了更多利用此数据类型的工具。Memcached不支持任何一种。
字符串对于各种用例都是有用的,这就是为什么memcached仅对这种数据类型有用。
哈希有点像键值存储中的键值存储。它们在字符串字段和字符串值之间映射。使用散列的Field-> value映射比使用常规字符串的key-> value映射具有更高的空间效率。
散列可用作名称空间,或者在逻辑上将许多键分组时很有用。使用散列,您可以有效地捕获所有成员,一起使所有成员到期,一起删除所有成员,等等。对于需要将多个键/值对进行分组的用例而言,它非常有用。
哈希的一种示例用法是在应用程序之间存储用户配置文件。使用用户ID作为密钥存储的Redis哈希将允许您根据需要存储有关用户的数据,同时将其存储在单个密钥下。使用散列而不是将配置文件序列化为字符串的优点是,您可以让不同的应用程序在用户配置文件中读/写不同的字段,而不必担心一个应用程序覆盖其他应用程序所做的更改(如果您将陈旧序列化,则会发生这种情况数据)。
Redis列表是字符串的有序集合。它们经过优化,可从列表的顶部或底部(又名:左或右)插入,读取或删除值。
Redis的提供许多命令为利用列表,包括命令到压入/弹出的项目,推/列表,截断列表之间弹出,执行范围查询等
列表使持久的,原子的队列成为可能。这些非常适合作业队列,日志,缓冲区和许多其他用例。
集是唯一值的无序集合。它们经过优化,可让您快速检查值是否在集合中,快速添加/删除值,以及测量与其他集合的重叠。
这些功能非常适合访问控制列表,唯一的访客跟踪器以及许多其他功能。大多数编程语言都有类似的东西(通常称为Set)。就是这样,只有分布式。
Redis提供了一些命令来管理集合。存在诸如添加,删除和检查集合之类的显而易见的内容。因此,不太明显的命令(例如弹出/读取随机项)以及用于执行与其他集合的并集和交集的命令。
排序集也是唯一值的集合。顾名思义,这些是有序的。它们按分数排序,然后按字典顺序排序。
此数据类型经过优化,可按分数快速查找。获得最高,最低或介于两者之间的任何值都非常快。
如果将用户以及他们的高分添加到排序的集合中,则您将拥有一个完美的排行榜。随着新的高分出现,只需将他们的高分再次添加到集合中,它将重新排列排行榜。也非常适合跟踪用户上次访问的时间以及谁在您的应用程序中处于活动状态。
存储具有相同分数的值会使它们按字典顺序(按字母顺序思考)排序。这对于自动完成功能等很有用。
许多排序的set 命令类似于set 命令,有时带有附加的score参数。还包括用于管理分数和按分数查询的命令。
Redis的具有几个命令用于存储,检索,以及测量的地理数据。这包括半径查询和测量点之间的距离。
从技术上讲,Redis中的地理数据存储在排序集中,因此这不是真正的独立数据类型。它更多地是对排序集的扩展。
像geo一样,这些也不是完全独立的数据类型。这些命令使您可以将字符串数据视为位图或超级日志。
位图是我在Strings
下面引用的位级运算符的作用。这种数据类型是reddit最近的合作艺术项目r / Place的基本构建块。
HyperLogLog允许您使用恒定的极少量空间以惊人的精度计算几乎无限的唯一值。仅使用〜16KB,您就可以有效地计算网站唯一身份访问者的数量,即使该数量是数百万。
Redis中的命令是原子性的,这意味着您可以确保在向Redis写入值后,该值对于连接到Redis的所有客户端都是可见的。无需等待该值传播。从技术上讲,memcached也是原子的,但是redis在memcached之外添加了所有这些功能,值得注意的是,所有这些其他数据类型和功能也是原子的。
尽管与关系数据库中的事务不太相同,redis也具有使用“乐观锁定”的事务(WATCH / MULTI / EXEC)。
Redis提供了一个称为“ 流水线 ” 的功能。如果要执行许多redis命令,则可以使用流水线将它们一次发送一次,而不是一次发送到redis。
通常,当您执行命令以进行redis或memcached时,每个命令都是一个单独的请求/响应周期。使用流水线,redis可以缓冲多个命令并一次执行所有命令,并在一次回复中对所有命令的所有响应进行响应。
这可以使您在批量导入或涉及许多命令的其他操作上获得更大的吞吐量。
Redis具有专用于发布/订阅功能的命令,从而允许Redis 充当高速消息广播者。这允许单个客户端将消息发布到连接到通道的许多其他客户端。
Redis可以执行发布/订阅以及几乎所有工具。像RabbitMQ这样的专用消息代理可能在某些方面具有优势,但是事实是,同一台服务器还可以为您提供持久的持久队列以及您的发布/订阅工作负载可能需要的其他数据结构,Redis通常被证明是最好,最简单的工具为了工作。
您可以想到lua脚本,例如redis自己的SQL或存储过程。它的大小不一,但这个类比大都可行。
也许您希望redis执行复杂的计算。也许您负担不起事务回滚,需要保证复杂过程的每一步都将自动发生。这些问题以及更多问题可以通过lua脚本解决。
整个脚本是原子执行的,因此,如果您可以使逻辑适合lua脚本,则通常可以避免混淆乐观的锁定事务。
如上所述,redis包括对集群的内置支持,并与自己的称为的高可用性工具捆绑在一起redis-sentinel
。
毫不犹豫地,对于任何新项目或尚未使用memcached的现有项目,我建议在memcached上使用redis。
以上可能听起来像我不喜欢memcached。相反:它是一种功能强大,简单,稳定,成熟且经过强化的工具。甚至在某些用例中,它比redis快一点。我喜欢记忆快取。我只是认为这对未来的发展没有多大意义。
Redis可以做memcached所做的一切,通常更好。memcached的任何性能优势都是次要的且特定于工作负载。还有一些工作量的Redis会更快,而Redis可以做的事情却是memcached根本做不到的。面对功能上的巨大鸿沟,微小的性能差异似乎微不足道,而且两个工具是如此之快和高效,它们很可能是您不得不担心扩展的基础架构的最后一部分。
只有一种情况使memcached更有意义:将memcached用作缓存。如果您已经使用memcached进行缓存,请在满足您需要的情况下继续使用它。迁移到Redis可能不值得,如果您仅将Redis用于缓存,则可能无法提供足够的收益,值得您花时间。如果memcached不能满足您的需求,那么您可能应该改用Redis。无论您需要扩展到内存缓存之外还是需要其他功能,这都是事实。
如果使用Redis
您需要有选择地删除/过期缓存中的项目。(你需要这个)
您需要能够查询特定类型的键。eq。'blog1:posts:*','blog2:categories:xyz:posts:*'。哦耶!这个非常重要。使用此选项有选择地使某些类型的缓存项无效。您还可以使用它来使片段缓存,页面缓存,仅给定类型的AR对象等无效。
持久性(您也将需要此持久性,除非您对每次重新启动后都必须预热的缓存没有问题。对于很少更改的对象非常重要)
如果使用memcached
根据我的经验,Redis的稳定性要比Memcached好得多
Memcached是多线程且快速的。
Redis具有很多功能,并且速度非常快,但是由于它基于事件循环,因此完全限于一个内核。
我们都使用。Memcached用于缓存对象,主要是减少数据库上的读取负载。Redis用于诸如排序集之类的事情,对于汇总时间序列数据非常有用。
这太长了,无法发布为已经接受的答案的评论,因此我将其作为单独的答案
还需要考虑的一件事是,您是否希望对缓存实例具有严格的内存上限。
由于redis是具有大量功能的nosql数据库,并且缓存仅是可以使用的一个选项,因此它会根据需要分配内存-放入的对象越多,使用的内存就越多。该maxmemory
选项没有严格强制使用内存上限。当您使用缓存时,密钥将被逐出并过期。可能是您的密钥的大小不尽相同,因此会发生内部存储器碎片。
默认情况下,redis使用jemalloc内存分配器,该内存分配器尽力做到紧凑和快速,但它是通用内存分配器,无法跟上大量分配和对象清除的速度。因此,在某些负载模式下,由于内部碎片,redis进程显然会泄漏内存。例如,如果您有一台具有7 Gb RAM的服务器,并且想将Redis用作非持久LRU缓存,则可能会发现Redis进程与maxmemory
随着时间的推移,将设置为5Gb会使用越来越多的内存,最终达到RAM的总限制,直到内存不足的杀手进行干预。
memcached更适合上述情况,因为它以完全不同的方式管理内存。memcached会分配一大块内存(它将需要的一切),然后使用自己实现的slab分配器自行管理该内存。而且,当在考虑对象大小的情况下完成LRU逐出时,memcached会努力将内部碎片保持在较低水平,因为它实际上使用了按板的LRU算法。
话虽如此,memcached在必须强制使用和/或可预测内存使用的环境中仍然占有重要地位。我们尝试使用最新的稳定redis(2.8.19)作为工作负载10-15k op / s的基于LRU的非持久性基于Memcached的替换,它泄漏了很多内存;由于相同的原因,相同的工作负载在一天左右的时间内使Amazon的ElastiCache redis实例崩溃。
maxmemory
选项不考虑内部内存碎片。请查看上面的评论以获取详细信息-在启用了内存限制选项的“ Redis作为LRU缓存”页面中描述的情况下,已经看到了我所描述的问题。另一方面,memcached使用不同的方法来避免内存碎片问题,因此其内存限制更为“困难”。
Memcached擅长于简单的键/值存储,擅长做键=> STRING。这使得它非常适合会话存储。
Redis擅长执行key => SOME_OBJECT。
这实际上取决于您要放入的内容。我的理解是,就性能而言,它们是相当均匀的。
如果您发现一些客观基准,也很幸运,如果您确实找到一些基准,请按我的方式发送。
如果您不介意粗俗的写作风格,那么从可用性的角度来看,Systoilet博客上的Redis vs Memcached值得一读,但是在得出任何性能方面的结论之前,请务必先阅读注释中的来回内容。存在一些方法上的问题(单线程繁忙循环测试),自从撰写本文以来,Redis也进行了一些改进。
毫无疑问,没有任何基准测试链接是完整的,因此也请在Dormondo的LiveJournal和Antirez Weblog上查看一些相互矛盾的基准测试。
编辑 -正如Antirez指出的那样,Systoilet分析是一个错误的构想。即使超出单线程不足,那些基准测试中的许多性能差异也可以归因于客户端库而不是服务器吞吐量。实际上,Antirez Weblog上的基准确实提供了更多的苹果对苹果(具有相同口)的比较。
我有机会在我使用过的缓存代理中同时使用memcached和redis,让我分享一下我在其中使用过什么和背后原因的确切位置...。
Redis>
1)用于为群集上的缓存内容建立索引。我在Redis群集上分布着超过十亿个密钥,Redis响应时间相当短且稳定。
2)基本上,它是一个键/值存储库,因此在您的应用程序中任何有相似之处的地方,都可以使用redis进行很多操作。
3)Redis持久性,故障转移和备份(AOF)将使您的工作更加轻松。
内存缓存>
1)是,可以用作缓存的优化内存。我用它来存储缓存内容,访问频率非常高(每秒50次),大小小于1 MB。
2)当我的单个内容大小> 1MB时,我也仅在16 GB内存中分配了2GB的内存缓存。
3)随着内容的增长接近极限,我偶尔会在统计数据中观察到更高的响应时间(redis则不是)。
如果您需要总体体验,Redis易于配置,非常绿色,具有稳定可靠的功能,非常灵活。
此外,此链接提供了一个基准测试结果,以下是来自同一方面的一些亮点,
希望这可以帮助!!
测试。运行一些简单的基准测试。很长一段时间以来,我认为自己是一头古老的犀牛,因为我主要使用内存缓存,并认为Redis是新来的孩子。
在我目前的公司中,Redis被用作主缓存。当我挖到一些性能统计和简单的开始测试,Redis的是,在性能方面,相当或微创慢比MySQL。
内存缓存虽然简单,但却使Redis 完全倒水。它的伸缩性更好:
此外,我认为内存缓存逐出策略得到了更好的实施,从而导致整体平均响应时间更加稳定,同时处理的数据量超过了缓存可以处理的范围。
一些基准测试表明,在我们的案例中,Redis的表现非常差。我认为这与许多变量有关:
就个人而言,我不同意Redis作者对并发和多线程的看法。
如果我们说redis是(cache +数据结构)的组合,而memcached只是一个缓存,那没有错。
一个非常简单的测试,用于针对redis-2.2.2和memcached设置并获取10万个唯一键和值。两者都在Linux VM(CentOS)上运行,而我的客户端代码(在下面粘贴)在Windows桌面上运行。
雷迪斯
存储100000个值所需的时间= 18954ms
加载100000个值所需的时间= 18328ms
记忆快取
存储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");
我们认为Redis是我们工作中的项目的重担。我们认为,通过使用一个模块在nginx
被称为HttpRedis2Module
或类似的方法,我们将拥有惊人的速度,但是在进行AB测试时,我们被证明是错误的。
也许模块不好或者我们的布局不好,但这是一个非常简单的任务,使用php提取数据然后将其填充到MongoDB中甚至更快。我们使用APC作为缓存系统,并使用php和MongoDB。当时要快得多nginx
Redis模块。
我的提示是自己进行测试,这样做将为您显示环境的结果。我们认为在我们的项目中不需要使用Redis,因为这没有任何意义。
Redis更好。
的优点Redis
是,
LUA
脚本)支持而Memcache
内存中键值缓存类型系统。
这是亚马逊提供的很棒的文章/不同之处
与memcached相比,Redis是明显的赢家。
Memcached只有一个加点, 它是多线程的,而且速度很快。Redis具有许多强大的功能,并且速度非常快,但仅限于一个内核。
有关Redis的要点,Memcached不支持这些要点