memcache和redis是互联网分层架构中最常用的KV缓存。很多同学在选择模型的时候都会纠结,是选择memcache还是redis。画外音:不鼓励粗暴的练习,比如“memcache提供的功能是redis提供的功能的一个子集,别想太多,你可以选择redis”。虽然redis比memcache出来的晚,功能也多,但是对于一个技术人来说,理解“为什么”恐怕比“选择谁”更重要。你倾向于什么时候选择redis?业务需求决定技术选择。当业务有这样的特点时,选择redis会更合适。一:需要支持复杂的数据结构。当value是hash、list、set、orderedset等复杂数据结构时,会选择redis,因为mc无法满足这些要求。最典型的场景,用户订单列表,用户留言,帖子评论列表等。第二:需要持久化。MC无法满足持久化的要求,只好选择redis。不过,这里要提醒的是,redis的持久化功能真的使用正确吗?不要把redis当数据库使用:redis的定期快照不能保证数据不丢失;redis的AOF会降低效率,无法支持数据量过大;不要指望redis在固化存储上比mysql做的好。不同的工具各有所长,使用redis作为数据库很可能是错误的。缓存场景和开启固化功能有什么优缺点?如果只缓存场景,数据存储在数据库中,缓存在redis中。此时如果开启固化功能:好处是redis挂掉再重启后,热数据可以快速恢复到内存中。它会立即对数据库施加压力,而无需缓存预热过程。缺点是在redis挂掉的过程中,如果数据库中有数据修改,可能会导致redis重启后数据库和redis的数据不一致。所以,对于只读场景,或者允许一些不一致的业务场景,可以尝试开启redis的固化功能。第三:需要天然的高可用。Redis天然支持集群功能,可以实现主动复制和读写分离。redis官方还提供了sentinel集群管理工具,可以实现主从服务监控和故障自动转移。所有这一切对客户端都是透明的,无需更改程序或人工干预。对于memcache,为了实现高可用,需要进行二次开发,比如客户端双读双写,或者服务端集群同步。不过,这里要提醒的是,在大多数业务场景下,缓存真的需要高可用吗?在缓存场景中,很多情况下,缓存不命中是允许的;当缓存宕机时,很多情况下可以通过DB读取数据;在业务场景中,高可用真的是缓存的主要需求吗?画外音:在即时通信业务中,用户的在线状态对可用性要求很高。第四:存储的内容比较大。memcache的值存储最大可达1M。如果存储的值非常大,只能使用redis。你什么时候更喜欢内存缓存?纯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会更快。最后,两点之一:代码可读性,代码质量,redis胜出。我看过mc和redis的代码。就可读性而言,redis是我见过最清爽的软件,没有之一。或许简单才是redis设计的初衷吧。编译redis甚至不需要configure或者依赖第一个三方库,一个make就可以搞定。至于memcache,可能是考虑了太多的扩展性和多系统兼容性,代码不清晰,显得费力。比如网络IO的部分,redis源码1-2个文件就可以搞定,mc用的是libevent,来回传一个fd,传pipe和thread,特别容易让人头晕。画外音:理论上mc只支持kv,redis支持那么多功能。mc的性能应该高很多很多,但事实并非如此。这可能真的与代码质量有关。第二:横向扩展需要应用自己解决。不管mc和redis,服务端集群天然不支持横向扩展,需要在客户端分片,其实对调用者不友好。如果服务器集群能支持横向扩展就更完美了。说了这么多,希望大家对redis和memcache有一个新的认识,哪怕是一点点。【本文为专栏作者《58神剑》原创稿件,转载请联系原作者】点此阅读更多该作者好文
