作者:Kaito
链接:kaito-kidd.com/2020/06/28/redis-vs-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。

总结

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

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

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

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

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

为什么 Redis 要比 Memcached 更火?相关推荐

  1. 为什么Redis要比Memcached更火?

    作者:Kaito 链接:kaito-kidd.com/2020/06/28/redis-vs-memcached/ 前言 我们都知道,Redis和Memcached都是内存数据库,它们的访问速度非常之 ...

  2. 为何Redis要比Memcached好用(转)

    转载链接:http://blog.csdn.net/renfufei/article/details/40598889 GitHub版本地址: https://github.com/cncounter ...

  3. 上海世博会很火,但这场大火似乎更火

    上海世博会很火,但这场大火似乎更火, 对死去者我们表示哀悼,我们更应该深思. 1.   几个无证的电焊工是这次事故的重要导火索之一 我对这个说法很无奈,所以对他们的指责我无法反驳,但我仍不忍! 有一种 ...

  4. MongoDB 或者 redis 可以替代 memcached 吗?

    著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:seamon 链接:http://www.zhihu.com/question/19645807/answer/12605 ...

  5. 比 Redis 还快,更省内存,惊爆了!

    点击关注公众号:互联网架构师,后台回复 2T获取2TB学习资源! 上一篇:Alibaba开源内网高并发编程手册.pdf 最近,一位前谷歌.前亚马逊的工程师推出了他创作的开源内存数据缓存系统 Drago ...

  6. 比 Redis 还快,更省内存,开源,惊爆了!

    今年年中,一位前谷歌.前亚马逊的工程师推出了他创作的开源内存数据缓存系统 Dragonfly,用 C/C++ 编写,基于 BSL 许可(Business Source License)分发. 根据过往 ...

  7. Redis之Vs Memcached

    面试官会问问你 redis 和 memcached 的区别,但是 memcached 是早些年各大互联网公司常用的缓存方案,但是现在近几年基本都是 redis,没什么公司用 memcached 了. ...

  8. linux redis 5.6扩展,Windows下为PHP5.6安装Redis扩展和memcached扩展

    2.根据PHP版本号,编译器版本号和CPU架构, 选择php_redis-2.2.5-5.6-ts-vc11-x64.zip和php_igbinary-1.2.1-5.5-ts-vc11-x64.zi ...

  9. 有了规范,第二代曲面电视会更火吗?

    不知道大家是否还记得小时候看过的熊猫等品牌的黑白电视机,它们并不是平面的,而是球面.此后10多年时间伴随着我们成长,平面电视逐步取代了球面电视.理论上来说,平面依然不是最适合人眼生理构造的形状,因为人 ...

最新文章

  1. 《需求分析》读后感之二
  2. 吴恩达家免费 NLP 课程重磅上线!110 个小视频教你做出聊天机器人,粉丝:我要让娃跟吴恩达姓!...
  3. 智源研究院发布世界首个“机器学习通用数学符号集”
  4. 解决错误:No module named ‘Cryptodome‘ 和错误rosbag.bag.ROSBagException: unsupported compression type: lz4
  5. LeetCode Rotate Array(数组的旋转)
  6. opsforlist 存在贼覆盖_RedisTemplate常用集合使用说明-opsForList(三)
  7. 用数据驱动思想来设计游戏-读《游戏编程精粹1》
  8. 查看MySQL服务端版本
  9. CSocket类的使用
  10. 数聚新动能 数创大未来——2016中国国际大数据大会
  11. pythonlambda回调函数_Python中如何借助lambda来给回调函数传参
  12. CTF之Web安全训练前篇1
  13. 【java与智能设备】01_2Android简介与环境搭建——开发环境
  14. Roberts算子边缘检测原理及实现
  15. Paypal Express Checkout介绍独立站一种付款选择
  16. 触摸屏是怎么控制PLC的?
  17. recyclerView的滑动
  18. vue全家桶+koa2+mongoDB打造全栈社区博客
  19. 中文邮件格式模板、工作汇报邮件模板这样写,90%人都爱看
  20. InvocationException: GraphViz‘s executables not found【BUG已解决】

热门文章

  1. boost源码剖析之:多重回调机制signal(下)
  2. Machine Learning week 11 quiz: Application: Photo OCR
  3. HashMap类Compute方法详解及样例
  4. C++ 3 基本数据类型
  5. 【济宁百瑞达机械设备有限公司——文化拓展学习】2018技术展望:利用现有IT投资扩大云部署...
  6. string类assign方法
  7. CDN服务技术架构图
  8. 统一代码风格工具 editorConfig
  9. 在 MySQL 中查找含有目标字段的表
  10. 菜鸟学习笔记2,$(document).ready()使用讨论