Redis和Memcached到底有什么区别?

前言

咱们都知道,Redis和Memcached都是内存数据库,它们的访问速度很是之快。但咱们在开发过程当中,这两个内存数据库,咱们到底要如何选择呢?它们的优劣都有哪些?为何如今看Redis要比Memcached更火一些?程序员

这篇文章,咱们就从各个方面来对比这两个内存数据库的差别,方便你在使用时,作出最符合业务须要的选择。web

要分析它们的区别,主要从如下几个方面对比:redis

  • 线程模型
  • 数据结构
  • 淘汰策略
  • 管道与事物
  • 持久化
  • 高可用
  • 集群化

总体比较

从以上几个方面进行对比分析,总结以下表。算法

比较点 Memcached Redis
线程模型 多线程 单线程
数据结构 仅支持string、value最大1M、过时时间不能超过30天 string、list、hash、set、zset、geo、hyperLogLog
淘汰策略 LRU LRU、LFU、随机等多种策略
管道与事物 不支持 支持
持久化 不支持 支持
高可用 不支持 主从复制+哨兵
集群化 客户端一致性哈希算法 主从复制+哨兵+固定哈希槽位

线程模型

要说性能,必需要分析它们的服务模型。spring

Memcached处理请求采用多线程模型,而且基于IO多路复用技术,主线程接收到请求后,分发给子线程处理。数据库

这样作好的好处是,当某个请求处理比较耗时,不会影响到其余请求的处理。微信

固然,缺点是CPU的多线程切换必然存在性能损耗,同时,多线程在访问共享资源时必然要加锁,也会在必定程度上下降性能。网络

Redis一样采用IO多路复用技术,但它处理请求采用是单线程模型,从接收请求处处理数据都在一个线程中完成。数据结构

这意味着使用Redis,一旦某个请求处理耗时比较长,那么整个Redis就会阻塞住,直到这个请求处理完成后返回,才能处理下一个请求,使用Redis时必定要避免复杂的耗时操做。多线程

单线程的好处是,少了CPU的上下文切换损耗,没有了多线程访问资源的锁竞争,但缺点是没法利用CPU多核的性能。

因为Redis是内存数据库,它的访问速度很是地快,因此它的性能瓶颈不在于CPU,而在于内存和网络带宽,这也是做者采用单线程模型的主要缘由。同时,单线程对于程序开发很是友好,调试起来也很方便。开发多线程程序必然会增长必定的调试难度。

所以,当咱们的业务使用key的数据比较大时,Memcached的访问性能要比Redis好一些。若是key的数据比较小,二者差异并不大。

严格来讲,Redis的单线程指的是处理请求的线程,它自己还有其余线程在工做,例若有其余线程用来异步处理耗时的任务。

Redis6.0又进一步完善了多线程,在接收请求和发送请求时使用多线,进一步提升了处理性能。

数据结构

Memcached支持的数据结构很单一,仅支持string类型的操做。而且对于value的大小限制必须在1MB如下,过时时间不能超过30天。

而Redis支持的数据结构很是丰富,除了经常使用的数据类型string、list、hash、set、zset以外,还可使用geo、hyperLogLog数据类型。

使用Memcached时,咱们只能把数据序列化后写入到Memcached中。而后再从Memcached中读取数据,再反序列化为咱们须要的格式,只能“整存整取”。

而Redis对于不一样的数据结构能够采用不一样的操做方法,很是灵活。

  • list:能够方便的构建一个链表,或者看成队列使用

  • hash:灵活地操做咱们须要的字段,进行“整存零取”、“零存整取”以及“零存零取”

  • set:构建一个不重复的集合,并方便地进行差集、并集运算

  • zset:构建一个排行榜,或带有权重的列表

  • geo:用于地图相关的业务,标识两个地点的坐标,以及计算它们的距离

  • hyperLogLog:使用很是少的内存计算UV

总之,Redis正是由于提供了这么丰富的数据结构,近几年在内存数据库领域大放异彩,为咱们的业务开发提供了极大的便利。

淘汰策略

Memcached必须设置整个实例的内存上限,数据达到上限后触发LRU淘汰机制,优先淘汰不经常使用使用的数据。

但它的数据淘汰机制存在一些问题:刚写入的数据可能会被优先淘汰掉,这个问题主要是它自己内存管理设计机制致使的。

Redis没有限制必须设置内存上限,若是内存足够使用,Redis可使用足够大的内存。

同时Redis提供了多种淘汰策略:

  • volatile-lru:从过时key中按LRU机制淘汰

  • allkeys-lru:在全部key中按LRU机制淘汰

  • volatile-random:在过时key中随机淘汰key

  • allkeys-random:在全部key中随机淘汰key

  • volatile-ttl:优先淘汰最近要过时的key

  • volatile-lfu:在全部key中按LFU机制淘汰

  • allkeys-lfu:在过时key中按LFU机制淘汰

咱们能够针对业务场景,使用不一样的数据淘汰策略。

管道与事物

Redis还支持管道功能,客户端一次性打包发送多条命令到服务端,服务端依次处理客户端发来的命令。这样能够减小来回往来的网络IO次数,提供高访问性能。

另外它还支持事物,这里所说的事物并非MySQL那样严格的事物模型,这种事物模型是Redis特有的。

通常事物会配合管道一块使用,客户端一次性打包发送多条命令到服务端,而且标识这些命令必须严格按顺序执行,不能被其余客户端打断。同时执行事务以前,客户端能够告诉服务端某个key稍后会进行相关操做,若是这个客户端在操做这个key以前,有其余客户端对这个key进行更改,那么当前客户端在执行这些命令时会放弃整个事务操做,保证一致性。

持久化

Memcached不支持数据的持久化,若是Memcached服务宕机,那么这个节点的数据将所有丢失。

Redis支持将数据持久化磁盘上,提供RDB和AOF两种方式:

  • RDB:将整个实例中的数据快照到磁盘上,全量持久化

  • AOF:把每个写命令持久到磁盘,增量持久化

Redis使用这两种方式相互配合,完成数据完整性保障,最大程度下降服务宕机致使的数据丢失问题。

高可用

Memcached没有主从复制架构,只能单节点部署,若是节点宕机,那么该节点数据所有丢失。业务须要对这种状况作兼容处理,当某个节点不可用时,把数据写入到其余节点以下降对业务的影响。

Redis拥有主从复制架构,两个节点组成主从架构,从能够实时同步主的数据,提升整个Redis服务的可用性。

同时Redis还提供了哨兵节点,在主节点宕机时,主动把从节点提高为主节点,继续提供服务。

主从两个节点还能够提供读写分离功能,进一步提升程序访问的性能。

集群化

Memcached和Redis都是由多个节点组成集群对外提供服务,但他们的机制也有所不一样。

Memcached的集群化是在客户端采用一致性哈希算法向指定节点发送数据,当一个节点宕机时,其余节点会分担这个节点的请求。

而Redis集群化采用的是每一个节点维护一部分虚拟槽位,经过key的哈希计算,将key映射到具体的虚拟槽位上,这个槽位再映射到具体的Redis节点。

同时每一个Redis节点都包含至少一个从节点,组成主从架构,进一步提升每一个节点的高可用能力。

当增长或下线节点时,须要手动触发数据迁移,从新进行哈希槽位映射。

Redis官方的集群化解决方案为Redis cluster,它采用无中心化的设计。另外也有第三方的采用中心化设计proxy方式的集群化解决方案,例如Codis、Twemproxy。

后面我会专门针对Redis集群化写一些文章详细介绍其内部的原理。

总结

总体来讲,Redis提供了很是丰富的功能,并且性能基本上与Memcached相差无几,这也是它最近这几年占领内存数据库鳌头的缘由。

若是你的业务须要各类数据结构给予支撑,同时要求数据的高可用保障,那么选择Redis是比较合适的。

若是你的业务很是简单,只是简单的set/get,而且对于内存使用并不高,那么使用简单的Memcached足够。

来源于:http://kaito-kidd.com/2020/06/28/redis-vs-memcached/

关注微信公众号:IT 老哥

回复:Java实战项目视频教程:便可获取200G,27套实战项目视频教程

回复:Java 学习路线,便可获取最新最全的一份学习路线图

回复:Java 电子书,便可领取 13 本顶级程序员必读书籍

回复:Java 全套教程,便可领取:Java 基础、Java web、JavaEE 所有的教程,包括 spring boot 等

回复:简历模板,便可获取 100 份精美简历



本文分享自微信公众号 - IT老哥(dys_family)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。