缓存数据库选型——redis和memcached

参考:《Memcached 与 Redis 实现的对比》《memcached redis 对比分析》

一、区别

1. redis支持的数据结构更丰富

redis:string、list、set、sorted set、hash table
memcached:string

2. redis支持数据持久化

redis:支持持久化
memcached:不支持持久化

3. redis支持分布式

redis:3.0之后支持服务端分布式
memcached:可以用客户端实现分布式

4. redis支持简单事务

redis:支持简单事务
(事务不支持回滚,它的事务只保证命令依次被执行,即使中间一条命令出错也会继续往下执行,所以说它只支持简单的事务;或者说redis的事务都不是事务,只是提供了一种方式,使得客户端可以一次性执行多条命令而已)
memcached:不支持事务

5. redis支持订阅与发布

订阅支持模糊匹配,发布不支持模糊匹配
发布给某个具体频道,但是接收者除了具体频道,还可能会有一些其他的监听者

6. memcached是多线程

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支持六种数据类型,因此能够更加智能地对数据进行缓存处理及操作,这相当于为应用程序开发人员敞开了一道通往无尽可能性的大门。

相对于将对象保存为序列化字符串,redis允许开发人员以散列方式将对象域及值加以保存,并利用单一键对其进行管理。redis散列机制的存在保证开发人员无需经历获取完整字符串、反序列化、更新值、对象重新序列化并在每次值更新后利用其替代缓存内完整字符串这一系列复杂的流程——这也意味着资源消耗量得以降低、性能表现迎来显著提升。redis所支持的其它数据类型,例如lists以及sets——也可被用于实现更加复杂的缓存管理模式。

redis的另一大重要优势在于,它所保存的数据具备透明化特性,也就是说服务器能够直接对这些数据进行操作。redis当中提供160多种可用命令,其中大部分用于实现数据处理操作并通过服务器端脚本将逻辑嵌入至数据存储体系当中。这些内置命令及用户脚本带来了极大的灵活性优势,足以帮助大家直接在redis内部完成数据处理任务——而不必将数据在网络中的其它专门处理系统之间来回移动。

redis还提供可选而且能够具体调整的数据持久性方案,其设计目的在于在发生规划内停机或者计划外故障之后对缓存内容进行重新引导。虽然我们更倾向于强调缓存内数据的易失性与暂时性,但将数据在磁盘中加以持久保存在某些缓存场景当中仍然极具现实意义。这种机制能够在设备重启之后快速将保存在磁盘上的数据重新载入至缓存当中,从而大大缩短缓存预热周期并根据主数据存储内容对当前缓存内容进行重新评估。

最后但也同样重要的一点是,redis能够提供复制功能。复制功能旨在帮助缓存体系实现高可用性配置方案,从而在遭遇故障的情况下继续为应用程序提供不间断的缓存服务。很明显,一套成熟的缓存方案应该能够在应用程序发生故障时略微甚至完全不给用户体验或者应用程序性能表现带来任何影响,而这种对缓存内容及服务可用性的有力保障在大多数情况下也成为缓存解决方案的一大主要优势。

三、小结

redis的作者Salvatore Sanfilippo曾经对这两种基于内存的数据存储系统进行过比较,总体来看还是比较客观的,现总结如下:

  1. 性能对比:由于redis只使用单核,而memcached可以使用多核,所以平均每一个核上redis在存储小数据时比memcached 性能更高。而在100k以上的数据中,memcached性能要高于redis,虽然redis最近也在存储大数据的性能上进行优化,但是比起memcached,还是稍有逊色。
  2. 内存使用效率对比:使用简单的key-value存储的话,memcached的内存利用率更高,而如果redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于memcached。另外,memcached使用预分配的内存池的方式,带来一定程度的空间浪费 并且在内存仍然有很大空间时,新的数据也可能会被剔除,而redis使用现场申请内存的方式来存储数据,不会剔除任何非临时数据 redis更适合作为存储而不是cache。
  3. redis支持服务器端的数据操作:redis相比memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果需要缓存能够支持更复杂的结构和操作,那么redis会是不错的选择。

四、贴一些前辈们使用redis的经验和教训:

  1. 要进行master-slave配置,出现服务故障时可以支持切换。
  2. 在master侧禁用数据持久化,只需在slave上配置数据持久化。
  3. 物理内存+虚拟内存不足,这个时候dump一直死着,时间久了机器挂掉。这个情况就是灾难。
  4. 当redis物理内存使用超过内存总容量的3/5时就会开始比较危险了,就开始做swap,内存碎片大。
  5. 当达到最大内存时,会清空带有过期时间的key,即使key未到过期时间。
  6. redis与DB同步写的问题,先写DB,后写redis,因为写内存基本上没有问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值