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

什么能给我们更好的表现?Redis和Memcached有什么优缺点吗?

需要考虑的要点:

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


当前回答

Redis更好。

Redis的优点是,

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

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

不支持各种数据类型存储,如列表、集合再贴现。主要缺点是Memcache没有磁盘持久性。

其他回答

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

我研究过的一些应用程序同时使用这两种方法,只是为了明确数据的行为方式-内存缓存中的数据,我们编写代码来处理数据不存在的情况-redis中的数据。

除此之外,Redis通常被视为优势,因为它的功能更丰富,因此更灵活。

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

Redis公司

存储100000个值所需的时间=18954ms加载100000个值所需的时间=18328ms

Memcached(内存缓存)

存储100000个值所需的时间=797ms检索100000个值所需的时间=38984毫秒


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

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

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

这太长了,不能作为已经接受的答案的评论发布,所以我将其作为单独的答案

还需要考虑的一件事是,是否希望对缓存实例设置硬内存上限。

由于redis是一个具有大量功能的nosql数据库,并且缓存是它唯一可以使用的选项,所以它可以根据需要分配内存-你在其中放置的对象越多,它使用的内存就越多。maxmemory选项没有严格执行内存使用上限。当您使用缓存时,密钥被收回并过期;很可能您的密钥大小不尽相同,因此会出现内部内存碎片。

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

memcached更适合上述场景,因为它以完全不同的方式管理内存。memcached分配了一大块内存,这是它所需要的一切,然后使用自己实现的slab分配器自行管理这些内存。此外,memcached努力保持内部碎片较低,因为它实际上使用了每片LRU算法,当考虑到对象大小时进行LRU驱逐。

尽管如此,memcached在内存使用必须强制执行和/或可预测的环境中仍然具有强大的地位。我们已经尝试使用最新的稳定redis(2.8.19)作为基于非持久性LRU的memcached替换,在10-15k op/s的工作负载下,它会大量泄漏内存;由于同样的原因,亚马逊的ElastiCache redis实例在一天左右的时间内崩溃。