画外音:不鼓励粗暴的实践,例如“memcache供应的功能是redis供应的功能的子集,不用想太多,选redis准没错”。
虽然redis比memcache更晚出来,且功能确实也更丰富,但对付一个技能人,理解“以是然”恐怕比“选择谁”更主要一些。

什么时候方向于选择redis?
业务需求决定技能选型,当业务有这样一些特点的时候,选择redis会更加适宜。
繁芜数据构造
value是哈希,列表,凑集,有序凑集这类繁芜的数据构造时,会选择redis,由于mc无法知足这些需求。
最范例的场景,用户订单列表,用户,帖子评论列表等。
持久化
mc无法知足持久化的需求,只得选择redis。
但是,这里要提醒的是,真的利用对了redis的持久化功能么?
千万不要把redis当作数据库用:
(1)redis的定期快照不能担保数据不丢失
(2)redis的AOF会降落效率,并且不能支持太大的数据量
不要期望redis做固化存储会比mysql做得好,不同的工具做各自善于的事情,把redis当作数据库用,这样的设计八成是缺点的。
缓存场景,开启固化功能,有什么利弊?
如果只是缓存场景,数据存放在数据库,缓存在redis,此时如果开启固化功能:
优点是,redis挂了再重启,内存里能够快速规复热数据,不会瞬时将压力压到数据库上,没有一个cache预热的过程。
缺陷是,在redis挂了的过程中,如果数据库中有数据的修正,可能导致redis重启后,数据库与redis的数据不一致。
因此,只读场景,或者许可一些不一致的业务场景,可以考试测验开启redis的固化功能。
天然高可用
redis天然支持集群功能,可以实现主动复制,读写分离。
redis官方也供应了sentinel集群管理工具,能够实现主从做事监控,故障自动转移,这统统,对付客户端都是透明的,无需程序改动,也无需人工参与。
而memcache,要想要实现高可用,须要进行二次开拓,例如客户真个双读双写,或者做事真个集群同步。
但是,这里要提醒的是,大部分业务场景,缓存真的须要高可用么?
(1)缓存场景,很多时候,是许可cache miss
(2)缓存挂了,很多时候可以通过DB读取数据
以是,须要负责阐发业务场景,高可用,是否真的是对缓存的紧张需求?
画外音:即时通讯业务中,用户的在线状态,就有高可用需求。
存储的内容比较大
memcache的value存储,最大为1M,如果存储的value很大,只能利用redis。
什么时候方向于memcache?
纯KV,数据量非常大,并发量非常大的业务,利用memcache或许更适宜。
这要从mc与redis的底层实现机制差异提及。
内存分配
memcache利用预分配内存池的办法管理内存,能够省去内存分配韶光。
redis则是临时申请空间,可能导致碎片。
从这一点上,mc会更快一些。
虚拟内存利用
memcache把所有的数据存储在物理内存里。
redis有自己的VM机制,理论上能够存储比物理内存更多的数据,当数据超量时,会引发swap,把冷数据刷到磁盘上。
从这一点上,数据量大时,mc会更快一些。
网络模型
memcache利用非壅塞IO复用模型,redis也是利用非壅塞IO复用模型。
但由于redis还供应一些非KV存储之外的排序,聚合功能,在实行这些功能时,繁芜的CPU打算,会壅塞全体IO调度。
从这一点上,由于redis供应的功能较多,mc会更快一些。
线程模型
memcache利用多线程,主线程监听,worker子线程接管要求,实行读写,这个过程中,可能存在锁冲突。
redis利用单线程,虽无锁冲突,但难以利用多核的特性提升整体吞吐量。
从这一点上,mc会快一些。
末了说两点
代码可读性,代码质量
看过mc和redis的代码,从可读性上说,redis是我见过代码最清爽的软件,乃至没有之一,或许大略是redis设计的初衷,编译redis乃至不须要configure,不须要依赖第三方库,一个make就搞定了。
而memcache,可能是考虑了太多的扩展性,多系统的兼容性,代码不清爽,看起来费劲。
例如网络IO的部分,redis源码1-2个文件就搞定了,mc利用了libevent,一个fd传过来传过去,又pipe又线程通报的,特殊随意马虎把人绕晕。
画外音:理论上,mc只支持kv,而redis支持了这么多功能,mc性能该当高非常多非常多,但实际并非如此,真的可能和代码质量有关。
水平扩展的支持
不管是mc和redis,做事端集群没有天然支持水平扩展,须要在客户端进行分片,这实在对调用方并不友好。如果能做事端集群能够支持水平扩展,会更完美一些。