为什么 Redis 要比 Memcached 更火?

简介: 前言我们都知道,Redis和Memcached都是内存数据库,它们的访问速度非常之快。但我们在开发过程中,这两个内存数据库,我们到底要如何选择呢?它们的优劣都有哪些?

为什么现在看Redis要比Memcached更火一些?


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


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


线程模型


数据结构


淘汰策略


管道与事务


持久化


高可用


集群化


线程模型

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


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


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


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


Redis同样采用IO多路复用技术,但它处理请求采用是单线程模型,从接收请求到处理数据都在一个线程中完成。推荐看一下这篇《Redis 到底是单线程还是多线程?》。


这意味着使用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正是因为提供了这么丰富的数据结构,近几年在内存数据库领域大放异彩,为我们的业务开发提供了极大的便利。关注公众号Java技术栈获取更多数据类型的详细使用教程。


淘汰策略

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


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


Redis没有限制必须设置内存上限,如果内存足够使用,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还提供了哨兵节点,在主节点宕机时,主动把从节点提升为主节点,继续提供服务。Redis哨兵如何与Spring Boot集成等系列教程可以关注公众号Java技术栈搜索阅读。


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


集群化

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


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


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


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


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


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


总结

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

网络异常,图片无法展示
|

整体来说,Redis提供了非常丰富的功能,而且性能基本上与Memcached相差无几,这也是它最近这几年占领内存数据库鳌头的原因。


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


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


如果此文章能给您带来小小的工作效率提升,不妨在看、转发一下,以鼓励我写出更好的文章!

————————————————

版权声明:本文为CSDN博主「Java技术栈」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/youanyyou/article/details/108526701

目录
相关文章
|
存储 NoSQL Redis
pyhon之对memcached及redis操作
pyhon之对memcached及redis操作
|
NoSQL 网络协议 应用服务中间件
redis,memcached,nginx网络组件
redis,memcached,nginx网络组件
126 0
|
存储 缓存 NoSQL
Redis问题之Redis与Memcached的主要区别是什么
Redis问题之Redis与Memcached的主要区别是什么
216 3
|
缓存 NoSQL Redis
【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?--epoll调用和中断
【5月更文挑战第18天】`epoll`包含红黑树和就绪列表,用于高效管理文件描述符。关键系统调用有3个:`epoll_create()`创建epoll结构,`epoll_ctl()`添加/删除/修改文件描述符,`epoll_wait()`获取就绪文件描述符。`epoll_wait()`可设置超时时间(-1阻塞,0立即返回,正数等待指定时间)。当文件描述符满足条件(如数据到达)时,通过中断机制(如网卡或时钟中断)更新就绪列表,唤醒等待的进程。
166 6
|
缓存 NoSQL 中间件
【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?epoll、poll和select + Reactor模式
【5月更文挑战第19天】`epoll`、`poll`和`select`是Linux下多路复用IO的三种方式。`select`需要主动调用检查文件描述符,而`epoll`能实现回调,即使不调用`epoll_wait`也能处理就绪事件。`poll`与`select`类似,但支持更多文件描述符。面试时,重点讲解`epoll`的高效性和`Reactor`模式,该模式包括一个分发器和多个处理器,用于处理连接和读写事件。Redis采用单线程模型结合`epoll`的Reactor模式,确保高性能。在Redis 6.0后引入多线程,但基本原理保持不变。
237 2
|
缓存 NoSQL Redis
【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?-- Redis多线程
【5月更文挑战第21天】Redis启用多线程后,主线程负责接收事件和命令执行,IO线程处理读写数据。请求处理流程中,主线程接收客户端请求,IO线程读取并解析命令,主线程执行后写回响应。业界普遍认为,除非必要,否则不建议启用多线程模式,因单线程性能已能满足多数需求。公司实际场景中,启用多线程使QPS提升约50%,或选择使用Redis Cluster以提升性能和可用性。
180 0
|
NoSQL Redis 数据库
【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?-- Memcache + Redis 多线程
【5月更文挑战第20天】Redis采用单线程模式以避免上下文切换和资源竞争,简化调试,且其性能瓶颈在于网络IO和内存,而非多线程。相比之下,Memcache使用多线程能更好地利用多核CPU,但伴随上下文切换和锁管理的开销。尽管Redis单线程性能不俗,6.0版本引入多线程以提升高并发下的IO处理能力。启用多线程后,Redis结合Reactor和epoll实现并发处理,提高系统性能。
244 0
|
存储 NoSQL Redis
11- Redis 和 Memcached 的区别有哪些?
Redis与Memcached的主要区别在于:Redis提供复杂数据结构和丰富的操作,而Memcached只支持简单字符串;Redis原生支持集群,Memcached不支持;Memcached数据无法持久化,重启会丢失,但Redis支持持久化并能在重启后恢复数据。
284 12
|
缓存 NoSQL Redis
Redis 和 Memcached 的区别
Redis和Memcached是两种常用的内存缓存系统,尽管它们都被用于提高应用程序的性能和扩展性,但它们在一些方面有所不同。
333 0
|
存储 缓存 NoSQL
redis 和 memcached 的区别
redis 和 memcached 的区别
197 0