Redis 和 Memcached 在选型上一直是个热门的话题。好多人想都不想,选用 Redis ,认为 Redis 的高IO性能。其实不然,还是得看在什么应用场景上。那么我们来探讨一下他们的相同点和不同点,然后再进行分析。
一、Redis 和 Memcached的相同点。
让我们先从二者的相似之处谈起。 Memcached 与 Redis 都属于内存内、键值数据存储方案。它们都从属于数据管理解决方案中的NoSQL 家族,而且都基于同样的键值数据模型。双方都选择将全部数据保存在内存当中,这自然也就让它们成为非常理想的缓冲层实现方案。从性能表现的角度来看,两类数据存储机制也具备诸多共通性,包括拥有几乎相同的特征(与指标)表现、而且高度关注工作负载的数据吞吐量与延迟状况。
除了同为内存内键值数据存储方案, Memcached 与 Redis 还都是相当成熟而且极具人气的开源项目。 Memcached 最初是由Brad Fitzpatrick于2003年开发而成,当时其直接服务对象为LiveJournal交友网站。在此之后, Memcached 被重新用C语言进行了编写(其最初实现方式为Perl语言)且投身于公共领域,并在这里逐步发展为现代 Web 应用程序的构建基石。 Memcached 项目的当前开发工作主要关注其运行稳定性及优化效果方面,而不再积极为其打造更多新型功能。
Redis 则由Salvatore Sanfilippo于2009年创建,而且时至今日Sanfilippo仍然担任着该项目的首席开发者以及惟一维护者的角色。Redis 有时候会被人们称为“强化版的 Memcached ”。考虑到从 Memcached 身上吸取并借鉴到大量宝贵的经验教训,这样的评价其实并不令人意外。 Redis 在功能多样性方面要胜过 Memcached ,这虽然让者更为强大也更具灵活性、但其复杂程度也较后者为甚。
作为两套被众多企业采纳并部署在无数关键性生产任务环境当中的解决方案, Memcached 与 Redis 在任何一种可行性编程语言领域都拥有能够提供支持的客户端库,而且二者也被包含在开发人员们使用的多种库及软件包之内。事实上,现在我们甚至已经很难找到一套不包含Memcached 或者 Redis 内置支持机制的 Web 堆栈。
Memcached 与 Redis 为什么如此受人拥戴?除了二者卓越的实际效果之外,双方各自极为简便的上手难度也是又一大加分项。无论是Memcached 还是 Redis ,其使用便捷性在开发人员当中都可谓广为人知。只需要几分钟我们就能完成安装工作,并让它们开始与应用程序顺畅协作。换句话来说,只需投入一小部分时间与精力,大家就能获得立竿见影且效果极佳的性能表现提升——具体而言,性能将直接步入新的量级。面对如此简单而又能够带来巨大收益的解决方案,又有谁能抗拒得了它们的诱惑呢?
二、什么情况下应该使用 Memcached
相对 Memcached 而言, Redis 的面世时间更晚且具备更多功能,因此开发人员通常将其视为默认性首选方案。不过有两类特殊场景仍然是 Memcached 的一家天下。首先就是对小型静态数据进行缓存处理,最具代表性的例子就是 HTML 代码片段。 Memcached 的内部内存管理机制虽然不像 Redis 的那样复杂,但却更具实际效率——这是因为 Memcached 在处理元数据时所消耗的内存资源相对更少。作为Memcached 所支持的惟一一种数据类型,字符串非常适合用于保存那些只需要进行读取操作的数据,因为字符串本身无需进行进一步处理。
除此之外, Memcached 在横向扩展方面也比 Redis 更具优势。由于其在设计上的思路倾向以及相对更为简单的功能设置,Memcached 在实现扩展时的难度比 Redis 低得多。不过根据我们了解到的情况,目前已经有多种经过测试且切实有效的方案能够将 Redis 扩展至多台服务器之上,而其即将发布的3.0版本(感兴趣的朋友可以点击此处查看其候选版本说明)将包含专门针对横向扩展场景的内置集群化机制。
三、什么情况下应该使用 Redis
除非大家需要考虑某种限定性条件(例如处理传统应用程序)对于Memcached
的特殊依赖性,或者自己的实际用例属于前面提到的两类场景中的一种,否则请直接选择Redis
并加以运用。凭借着Redis
所带来的卓越缓存方案,我们将拥有强大的处理能力——例如对缓存内容及持久性进行细节调整的能力——以及出色的整体执行效率。
Redis
几乎在缓存管理工作中的每一个侧面都表现出显而易见的优越性。这套缓存方案采用所谓数据回收机制,能够将陈旧数据从内存中删除以提供新数据所必需的缓存空间。 Memcached 的数据回收机制使用的是 LRU (即最低近期使用量)算法,而且往往会比较武断地直接删除掉与新数据体系相近的原有内容。相比之下, Redis 允许用户更为精准地进行细化控制,利用六种不同回收策略确切提高缓存资源的实际利用率。 Redis 还采用更为复杂的内存管理与回收对象备选方案。
Redis 还能为我们带来最大程度的灵活性空间,从而保证管理员在打理缓存对象时拥有充裕的施展平台。在这方面, Memcached 将键名限制在250字节,值也被限制在不超过1MB,且只适用于普通字符串。相比之下, Redis 则将键名与值的最大上限各自设定为512MB,且支持二进制格式。 Redis 支持5种数据类型,因此能够更加智能地对数据进行缓存处理及操作。
相对于将对象保存为序列化字符串, Redis 允许开发人员以散列方式将对象域及值加以保存,并利用单一键对其进行管理。 Redis 散列机制的存在保证开发人员无需经历获取完整字符串、反序列化、更新值、对象重新序列化并在每次值更新后利用其替代缓存内完整字符串这一系列复杂的流程——这也意味着资源消耗量得以降低、性能表现迎来显著提升。 Redis 所支持的其它数据类型,例如Lists以及Sets——也可被用于实现更加复杂的缓存管理模式。
Redis 的另一大重要优势在于,它所保存的数据具备透明化特性,也就是说服务器能够直接对这些数据进行操作。 Redis 当中提供160多种可用命令,其中大部分用于实现数据处理操作并通过服务器端脚本将逻辑嵌入至数据存储体系当中。这些内置命令及用户脚本带来了极大的灵活性优势,足以帮助大家直接在 Redis 内部完成数据处理任务——而不必将数据在网络中的其它专门处理系统之间来回移动。
Redis 还提供可选而且能够具体调整的数据持久性方案,其设计目的在于在发生规划内停机或者计划外故障之后对缓存内容进行重新引导。虽然我们更倾向于强调缓存内数据的易失性与暂时性,但将数据在磁盘中加以持久保存在某些缓存场景当中仍然极具现实意义。这种机制能够在设备重启之后快速将保存在磁盘上的数据重新载入至缓存当中,从而大大缩短缓存预热周期并根据主数据存储内容对当前缓存内容进行重新评估。
最后但也同样重要的一点是, Redis 能够提供复制功能。复制功能旨在帮助缓存体系实现高可用性配置方案,从而在遭遇故障的情况下继续为应用程序提供不间断的缓存服务。很明显,一套成熟的缓存方案应该能够在应用程序发生故障时略微甚至完全不给用户体验或者应用程序性能表现带来任何影响,而这种对缓存内容及服务可用性的有力保障在大多数情况下也成为缓存解决方案的一大主要优势。
开源软件业界一直在不断努力,为我们带来当下技术领域中最为出色的各类解决方案。而在谈到利用缓存机制对应用程序性能表现加以提升这一话题时, Redis 与 Memcached 作为两款广受赞誉而且久经考验的解决方案、也自然而然地成为完成这项任务的两大首选技术成果。不过从功能多样性以及设计先进性的角度出发, Redis 显然更适合被大家作为通用性的首选方案——除了少部分特殊场景之外。
关于性能比较:
下面的内容是来自Redis作者在stackoverflow上的一个回答,对应的问题是《Is memcached a dinosaur in comparison to Redis?》(相比Redis,Memcached真的过时了吗?)
- 没有必要过于关注性能,因为二者的性能都已经足够高了。由于Redis只使用单核,而Memcached可以使用多核,所以二者比较起来,平均每一个核上,Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis。虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。说了这么多,结论是,无论你使用哪一个,每秒处理请求的次数都不会成为瓶颈。另外, 根据网上测试数据: 10k-100k 数据中,二者差不多,10k以下则是redis性能比较好。
- 在内存使用效率上,如果使用简单的key-value存储,Memcached的内存利用率更高。而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。当然,这和你的应用场景和数据特性有关。
- 如果你对数据持久化和数据同步有所要求,那么推荐你选择Redis。因为这两个特性Memcached都不具备。即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。
- 当然,最后还得说到你的具体应用需求。Redis相比Memcached来说,拥有更多的数据结构,并支持更丰富的数据操作。通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果你需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。