选redis还是memcache,源码怎么说?

memcacheredis互联网分层架构中,最常用的KV缓存。不少同学在选型的时候会纠结,到底是选择memcache还是redis
画外音:不鼓励粗暴的实践,例如“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会快一些
 
最后说两点
其一:代码可读性,代码质量,redis完胜。
看过mc和redis的代码,从可读性上说,redis是我见过代码最清爽的软件,甚至没有之一,或许简单是redis设计的初衷,编译redis甚至不需要configure,不需要依赖第三方库,一个make就搞定了。
 
而memcache,可能是考虑了太多的扩展性,多系统的兼容性,代码不清爽,看起来费劲。
 
例如网络IO的部分,redis源码1-2个文件就搞定了,mc使用了libevent,一个fd传过来传过去,又pipe又线程传递的,特别容易把人绕晕。
画外音:理论上,mc只支持kv,而redis支持了这么多功能,mc性能应该高非常多非常多,但实际并非如此,真的可能和代码质量有关。
 
其二:水平扩展,都需要应用自己解决。
不管是mc和redis,服务端集群没有天然支持水平扩展,需要在客户端进行分片,这其实对调用方并不友好。如果能服务端集群能够支持水平扩展,会更完美一些。
 
说了很多,希望大家对redis和memcache有了新的认识,哪怕是一点点。

选redis还是memcache,源码怎么说?

架构师之路-分享技术思路

相关推荐:
不用缓存服务,还能怎么缓存数据?
群消息,究竟存1份还是多份?
技术人,谢

发布者:糖太宗,转载请注明出处:https://www.qztxs.com/archives/science/technology/6843

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022年5月15日 下午9:17
下一篇 2022年5月15日 下午9:18

相关推荐

  • 信息安全规划文档的编写 (转发)

    0-00 安全规划的目的 组织安全部门建立到运行一段的时间,工作阶段从救火到标准化的过程就需要考虑编制和实施适合自己组织的安全规划了。 编写安全规划主要为以后的工作进行合理的估计和安排,从结构上提升组织的安全水平,大概是从杂牌军到正规军的转变,也有可能现有的方法满足不了实际业务的需求,需要重新规划、设计。   0-01 安全规划应该包含的内容 安全...

    技术 2022年6月16日
    2700
  • OpenVPN + Ldap + OTP

    OpenVPN 服务端的一些配置 VPN是企业内比较重要的一个资产,不能从网上乱下载,去官网看看 https://openvpn.net/,第一次不懂事,不清楚OpenVPN还有商业版,OpenVPN Access Server 和 OpenVPN Community,直接就安装了OpenVPN AS,没有网上说的那么难,还有图形化界面,登陆进行发现2个并发...

    技术 2022年5月28日
    59100
  • Linux环境变量设置

    0x00 查看环境变量 查看环境变量有三个命令: env:env命令是environment的缩写,用于列出所有的环境变量 export:单独使用export命令也可以像env列出所有的环境变量,不过export命令还有其他额外的功能 echo $PATH:echo $PATH用于列出变量PATH的值,里面包含了已添加的目录   0x01 设置环境...

    技术 2022年6月1日
    1400
  • IAST测试靶场搭建

    0x00 前言 测试用例的选择尽量贴近真实业务使用的场景,覆盖常见的高危漏洞,以及各类请求形式。用于测试IAST产品支持检测漏洞类型、检出率、脏数据插入等等   0x01 靶场选择 靶场 DVWA Openrasp-testcases 技术栈 PHP/MYSQL JAVA/PHP/MYSQL 支持漏洞类型 https://github.com/di...

    2022年6月13日
    10900
  • 又一个,时间复杂度为O(n)的排序!

    桶排序(Bucket Sort),是一种时间复杂度为O(n)的排序。 画外音:百度“桶排序”,很多文章是错误的,本文内容与《算法导论》中的桶排序保持一致。   桶排序的适用范围是,待排序的元素能够均匀分布在某一个范围[MIN, MAX]之间。 画外音:很多业务场景是符合这一场景,待排序的元素在某一范围内,且是均匀分布的。   桶排序需要两个辅助空间: (1)...

    2022年5月11日
    1400

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信