Memchached 还是 Redis?
该用哪一个?当我们讨论改进性能的时候,这是每次技术讨论中最常见的一个问题。每当性能需要改善时,采用缓存常常是迈出的第一步。与此同时,选择Memcached 或者 Redis 通常是第一个需要考虑的地方。哪个能给我们提供更佳的性能?它们的优点和缺点又是什么?
在设计任何缓存系统时,我们考虑如下几点:
- 读/写速度
- 内存使用情况
- 磁盘 I/O 转储.
- 伸缩性.
我写这篇教程是考虑到你已经知道了这些缓存的基础知识。
Redis & Memchached 之间的相似之处:
Memcached/Redis 两者都提供基于内存的、键-值数据存储,尽管Redis更准确的说是结构化数据存储。Redis是内存中的结构化数据存储器,用于数据库、缓存、消息代理。两者(Memcached/Redis)都属于数据管理方案中的NoSQL家族,都是基于键-值存储的。它们都在内存中保存数据,当然使它们作为缓存层特别有用。
截至今日,Memcached提供的每项主要功能及其优势,都是Redis功能和特性的子集。任何用例中可能使用Memcached的地方都可以对等的使用Redis。它们都是闪电般快速的高速缓存。Memcached提供的只是Redis拥有功能的冰山一角。Memcached是一个基于易失性内存的键-值存储器。Redis一样可以做到(跟Memcached做得一样好),但是它还是一个结构化数据服务器。
为什么选 Memcached?
当缓存相对较小和使用静态的数据时候,比如HTML代码片段,Memcached可能更为可取。Memcached内部的内存管理在最简单的用例中更为有效,因为它的元数据消耗相对更少的内存资源。
当数据尺寸是动态的时候,Memcached的内存管理效率下降的很快,此时Memcached的内存会变成碎片。而且,大的数据集经常牵扯到数据序列化,总是需要更多的空间来存储。如果你使用Memcached,数据会随着重启动而丢失,重建缓存是个代价高昂的过程。
Memcached比Redis更具优势的另一个场景在伸缩性。因为Memcached是多线程的,所以你可以通过给它更多计算资源让它轻松扩展。Redis是单线程的,可以通过集群无损水平扩展。集群是一个有效的扩展方案,但是相对来说配置、操作复杂。Memcached不支持复制功能(数据从一台机器自动复制到另外一台)。
Memcached 非常适合处理高流量的网站。它可以一次性读取大量的信息,并在优秀的反应时间内返回。Redis不但能处理高流量的读,还能处理繁重的写入。
为什么选 Redis?
Redis有五种主要的数据结构可以选择。通过对缓存数据智能化的缓存和处理,它为应用程序开发人员打开了存在各种可能的新世界。由于其数据结构(使用多种格式存储数据:列表、数组、集合、有序集合)特性,Redis作为缓存系统提供了更多的能力和总体上更好的效率。缓存使用一种称为“数据回收”的机制,通过从内存中删除旧数据为新数据腾出空间。Memcached的数据回收机制使用了LRU(Least Recently Used-最近最少使用)算法,但回收与新数据近似大小的数据时有点随意性。
Redis允许对回收进行细粒度的控制,让你选择六种不同的回收策略。Redis同时支持惰性(被动)和主动回收,只有在需要更多空间或主动激活时才回收数据。另一方面,Memcached只支持惰性回收。
以下是redis提供的一些功能,可以用于“真实”数据存储,而不仅仅是缓存。
- 强大的数据类型和可利用它们的强大命令支持。哈希、有序集合、列表等。
- 默认的磁盘持久化支持
- 使用乐观锁的事务支持 (WATCH/MULTI/EXEC)
- 发布/订阅功能,速度极快
- 高达512MB的键值尺寸上限(Memcached每个键值限于1MB大小)
- Lua 脚本支持 (2.6及以上版本)
- 内置集群支持 (3.0及以上版本)
- 一切都极快
强大的数据类型尤为重要。它们允许Redis提供一个出色的共享队列(list),一个很棒的消息传递解决方案(pub/sub),一个存储会话信息(hashes)的好地方,还有一个引人注目的高分值追踪区域(sorted sets)。它们仅仅是简单探讨就能得到的使用样例。
结论
Redis与Memcached相比,性能和内存使用情况相当相似。除非你已经在Memcached上投入了大笔资金,否则向前推进使用Redis是显而易见的解决方案。不仅Redis是更好的选择,它还支持全新类型的用例和使用模式。
Redis可能会非常有用的一些示例应用程序:
-
电子商务应用:大多数的电子商务应用量级比较重,Redis可以提升你的页面加载速度。你可以存储所有的配置文件到Redis,从内存中读取这些配置信息速度会非常快速。你也可以在Redis中存储完整的页面缓存,因为它的键值容量很大。你也可以存储会话信息到Redis。
-
物联网应用:在物联网应用中,物联网设备非常频繁的发送数据到服务器,比如每秒钟数千条。在把它们存储到任何持久性存储器之前,你可以先把这些高容量的原始数据推送到Redis。
-
实时分析:可以在Memcached上实现一个实时的分析引擎,以数据库为后盾。但是Redis非常擅长统计列表和一系列事物。在所有的Redis功能特性中,它对键值进行排序的能力超过了Memcached,还有计算一组页面的点击次数等数据,然后将这些数字汇总进入分析系统。这些数据可通过工作人员输入到更大的分析引擎,在这些应用场合选择Redis是正确的决定之一。
最后一件事:不管你选择什么,缓存系统都不是数据库。你不能光靠缓存,系统同时需要缓存和数据库。
这段是我的评论。总体上看,Redis功能特性远优于Memcached,完全是下一代产品。选择哪个使用似乎答案很明确。但是必须指出,Redis的单线程设计,同时也带来了一些重要的隐患。Redis有数据持久化功能,这个功能与Redis的单线程特性结合,就成了Redis故障的高发区域。默认的RDB持久化会阻塞线程,使得Redis对正常请求无法响应,在高流量网站上容易出现大量请求错误。这在系统中称为“涌现”,当然这是坏的一个。当然后来Redis也发展出了AOF持久化方式(默认没有打开,要手工开启),一定程度上减缓了Redis的持久化问题。Redis会fork一个子进程来单独处理持久化。可是fork功能并非无代价,它一样有消耗内存资源,影响主程序响应请求的问题。阻塞是Redis应用的噩梦,跟Node.js一样。所以出现故障的时候,可以多在这个角度上分析原因,也许能很快的解决。