分享好友 最新动态首页 最新动态分类 切换频道
Redis缓存问题与缓存更新机制详解
2025-02-03 14:46
一、缓存问题1.1 缓存穿透1.1.1 问题来源1.1.2 解决方案1.2 缓存击穿1.2.1 问题来源1.2.2 解决方案1.3 缓存雪崩1.3.1 问题来源1.3.2 解决方案二、缓存更新机制2.1 缓存更新策略分类2.2 内存淘汰机制2.2.1 noeviction2.2.2 volatile-lru2.2.3 volatile-lfu2.2.4 volatile-ttl2.2.5 volatile-random2.2.6 allkey-lru2.2.7 allkey-lfu2.2.8 allkey-random2.3 超时剔除2.3.1 定时删除2.3.2 惰性删除2.4 主动更新2.4.1 主动更新策略2.4.2 主动更新策略需要考虑的三个问题2.5 缓存更新机制总结总结

1.1.1 问题来源

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求。由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。

1.1.2 解决方案

1.1.2.1 缓存空对象

从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击。

1.1.2.2 使用布隆过滤器

类似于一个hash set,用于快速判某个元素是否存在于集合中,其典型的应用场景就是快速判断一个key是否存在于某容器,不存在就直接返回。布隆过滤器的关键就在于hash算法和容器大小。

1.2.1 问题来源

缓存击穿是指缓存某些热点数据失效(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。

1.2.2 解决方案

1.2.2.1 设置热点数据永远不过期

可以在刷缓存时,设置热点数据不过期。

1.2.2.2 新增后台定时更新缓存线程(逻辑不过期)

后台新增一个缓存更新线程,缓存快要过期前刷新缓存时间,防止缓存失效。

1.2.2.3 使用分布式互斥锁

可以使用Redis提供的分布式互斥锁,保证只有一个请求查询数据库和更新缓存,其他请求阻塞等待缓存更新完成后在访问缓存。

1.2.2.4 接口限流与熔断,降级

重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些服务不可用时候,进行熔断,失败快速返回机制。

1.3.1 问题来源

缓存雪崩是指Redis缓存不能正常提供服务了(阻塞、服务宕机、大面积缓存失效等造成),导致所有请求都落到了数据库上,增加了数据库压力或者导致数据库宕机。

1.3.2 解决方案

1.3.2.1 缓存过期时间随机

缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。

1.3.2.2 分布式部署

采用分布式部署方式部署缓存,避免缓存服务单节点,同时将热点数据均匀分布在不同的缓存数据库中。

1.3.2.3 设置热点数据永远不过期

可以在刷缓存时,设置热点数据不过期。

1.3.2.4 接口限流与熔断,降级

重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些服务不可用时候,进行熔断,失败快速返回机制。

内存淘汰超时剔除主动更新说明重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些服务不可用时候,进行熔断,失败快速返回机制。给缓存数据添加TTL时间,到期后自动删除缓存,下次查询时更新缓存编写业务逻辑,在修改数据的同时,更新缓存一致性差一般好维护成本无低高

2.2.1 noeviction

不淘汰,这是默认的淘汰策略;

当内存达到限制后,写请求(set)会返回错误,读请求(get)和删除请求(del)可以继续进行

2.2.2 volatile-lru

内存不足时,在设置了过期时间的key中,优先删除最近最少使用的key

2.2.3 volatile-lfu

内存不足时,在设置了过期时间的key中,优先删除使用频率最少的key

2.2.4 volatile-ttl

内存不足时,在设置了过期时间的key中,优先删除存活剩余时间最少的key

2.2.5 volatile-random

内存不足时,在设置了过期时间的key中,随机删除某个key

2.2.6 allkey-lru

内存不足时,在全体key范围内,优先删除最近最少使用的key

2.2.7 allkey-lfu

内存不足时,在全体key范围内,优先删除使用频率最少的key

2.2.8 allkey-random

内存不足时,在全体key范围内,随机删除某个key

2.3.1 定时删除

设置一个定时任务,随机抽取部分过期时间的key,检查是否过期,过期了就清除掉

2.3.2 惰性删除

查询获取数据时,检查缓存是否过期,过期则删除,没过期不删除

Redis 默认采用惰性删除+定时删除结合的过期策略

2.4.1 主动更新策略

2.4.1.1 Cache Aside Pattern

由缓存的调用者在更新数据库的同时更新缓存

2.4.1.2 Read/Write Through Pattern

缓存和数据库整合为一个服务,由服务来维护一致性。调用者调用服务,不用关心一致性问题。

2.4.1.3 Write Behind Caching Pattern

调用者只操作缓存,由其他线程异步的将缓存数据持久化到数据库,最终保持一致。

在企业中使用最多的主动更新策略是 Cache Aside Pattern。也就是我们自己编码来保证数据的一致性。

2.4.2 主动更新策略需要考虑的三个问题

2.4.1 删除缓存还是更新缓存?

2.4.1.1 删除缓存

更新数据库时让缓存失效,查询时再更新缓存。(延迟加载)一般选择这个方案。

这个方案比较合理一点,可以避免过多的无效写操作,缓存删除后,只要没人来查询这条数据,数据就不会被写入缓存,这样就可以避免大量无效的写操作

2.4.1.2 更新缓存

每次更新数据库都更新缓存,无效写操作比较多。

这种方式的缺点很明显,举个例子:假如我更新了100次数据库,然后又同时更新了100次缓存,但是在更新的时候并没有人来查这个数据,那么我更新这100次缓存好像也没啥用吧,相当于前99次都是无用功,只有最后一次才是有用的。这就是无效写操作过多的原因。

2.4.2 如何保证缓存与数据库的操作同时成功或失败?

1)单体系统,将缓存与数据库操作放在一个事务中。

2)分布式系统,利用TCC等分布式事务方案。

2.4.3 先操作缓存还是数据库?

2.4.3.1 先删除缓存,再操作数据库

这种方式存在很明显的问题,假设有两个并发操作,线程A更新,线程B查询。线程A先删除缓存,然后还没来得及更新数据库,CPU资源被线程B抢走,线程B查询缓存发现没有命中(因为已经被线程A删除了),查询数据库,然后把结果写入到缓存中。这个时候线程A终于抢到CPU资源了,然后更新数据库,此时就会造成数据不一致问题。

2.4.3.2 先操作数据库,再删除缓存

这种处理方式使用的频率是最高的,因为出错的概率非常小,只有一种比较极端的情况才会出现数据一致性问题。

同样有两个并发请求,线程A查询、线程B更新,当线程A查询的时候,缓存刚好失效,然后就去查询数据库拿到数据,在准备写入缓存的时候,CPU资源被线程B抢走,线程B开始更新数据库,然后删除缓存(这一步其实等于无用,因为缓存已经过期)。此时线程A再次获取到CPU资源,然后写入缓存,此时写入的是更新前的旧数据,会产生数据一致性问题。

看起来这确实也是一个问题,但是我们仔细分析一下这种情况都需要满足哪些条件:

1)并发读写操作2)读缓存时,缓存刚好失效3)写数据库操作要比写缓存快

写数据库是操作磁盘,写缓存是操作内存的,所以不太可能会出现写磁盘的速度快于写内存的。因此使用这种方式出现数据一致性的概率是很小的。

2.4.3.3 延时双删策略

延迟双删策略是分布式系统中数据库存储和缓存数据保持一致性的常用策略,但它不是强一致。其实不管哪种方案,都避免不了Redis存在脏数据的问题,只能减轻这个问题,要想彻底解决,得要用到同步锁和对应的业务逻辑层面解决。

前面两种方案的不足点我们进行了分析,第二种方式的使用频率比较高,但是也有一些小缺陷,虽然说发生的概率很低,但是这个概率到了线上会不会发生也不好说,所以就有了延时双删策略对第二种方式做补充。

所谓延时双删就是先进行缓存清除,再执行数据库操作,最后(延迟N秒)再执行缓存清除。延迟N秒的时间要大于一次写操作的时间,这个延时N秒就是了完善保证第二种策略中不足,可以保证线程A的写缓存和线程B的修改数据库、删除缓存都执行完毕,然后再删除缓存一次,就可以保证后面再来的查询请求可以查询到最新数据。

ps: 一般的延时时间设置为3S左右,具体情况要根据业务场景取最佳值。

1)内存淘汰:不用自己维护,利用Redis内存淘汰机制,自动删除部分缓存数据,这些被删除的数据在下一次被查询时更新。这种方式一致性最差。2)超时剔除:给缓存数据加上过期时间 ,到期后自动删除,下次查询时更新,数据一致性问题大概率会出现。维护成本比较低。3)主动更新:编写业务逻辑,在修改数据库的同时更新缓存,一致性比较好,维护成本比较高。一般采用先操作数据库再更新缓存的方式。

一般在数据一致性要求比较低的场景下可以使用内存淘汰机制,比如商城首页的分类信息,这些东西基本上是不会变化的。如果一致性要求比较高,我们可以采用主动更新+超时剔除兜底的方式来处理。

最新文章
个人彩铃怎么制作如何定制办理手机彩铃定制「个人彩铃怎么制作如何定制办理」
公司个人彩铃广告现在越来越被商家看好,资费低,开通方便,使用简单,一次,终身受益,一对一广告效果,100%针对性,等等,这些都是企业个人彩铃被快速推广的原因,随着人们对公司商务个人彩铃的不断认识升级与更新,使用的公司或单位也逐
电脑蓝屏故障大全手机蓝屏「电脑蓝屏故障大全」
电脑蓝屏故障大全  电脑蓝屏是经常使用电脑的朋友常会遇到的电脑故障,正是由于电脑蓝屏是一种非常普遍的现象,所以很难有预测性,有的时候在一些非常重要的场合也会出现电脑蓝屏现象,比如:xp系统创建者盖茨在介绍Windows 98 功能的发
清明节,你真没想过去趟呼和浩特?
这个清明节不妨来点特别的体验告别千篇一律的踏青来呼和浩特开启一场硬核怀古游吧在文博场馆里感受历史的厚重在城墙根下定格国风大片在古玩老街体验老物件的魅力这座国家历史文化名城藏着数不尽的古韵宝藏等你来开启第一站:博物馆里觅史踪
三星S25Ultra全程疯狂:无边环绕屏很炸裂三星曲面屏手机「三星S25Ultra全程疯狂:无边环绕屏很炸裂」
采用无边框环绕屏,再配备全程虚拟按键,这样的三星手机够不够疯狂?其实这是外媒曝光的三星S25Ultra概念设计图,直接拒绝采用直面屏,而是选择更疯狂的曲面环绕屏,将屏幕两侧的边框都干掉了,甚至连屏幕占比都超过100%,全部配备虚拟按键
分享所有人回不去的童年:所有人都在玩手机「分享所有人回不去的童年:」
晚上好,我是南有,昨晚和大家互动,说想听听你们童年的快乐回忆,没想到,真的收到了很多人的留言。 所以,今晚的推文真的很长很长,但希望你耐心看完,或许有些回忆也是你曾经有过的,只是生活太匆忙,我们都忘记了。 有的读者留言说自己
春水堂(情趣特卖商城)手机货到付款「春水堂(情趣特卖商城)」
想要拥有岛国小电影里面看到的各种新奇的玩具吗?那么就快使用春水堂app吧,这里有全国最大情趣用品特卖商城,你解我的风情,我解你的衣扣。【春水堂】随身带着性福的入口.【女神测评】我所有心思都集中在你短裙下,那一片我从未建庙修行的地
马略卡vs莱加内斯:塞尔希-达德尔、科佩特首发,德米特罗维奇、阿尔蒂米拉出战
北京时间4月20日西班牙足球甲级联赛联赛第32轮,马略卡主场对阵莱加内斯。马略卡首发:普拉茨, 拉林, 达尼-罗德里格斯, 塞尔希-达德尔, 萨穆-科斯塔, 莫希卡, 巴勃罗-马菲奥, 瓦连特, 科佩特, 赖洛, 格赖夫替补:马特乌-默雷伊, 托尼-拉托,
拓宽各民族全方位嵌入的云南实践
张睿莲习近平总书记考察云南时强调:“要加强边疆民族地区治理,拓宽各民族全方位嵌入的实践路径,深入推进新时代兴边富民行动,切实维护民族团结、边疆稳固。”这一重要指示,为云南“逐步实现各民族在空间、文化、经济、社会、心理等方面
曹世镐公开“将婚礼礼金放进保险柜”的客人,不是刘在石和权志龙
大家好呀,这里是你们的小娱~今天要聊的是韩国知名男星曹世镐在综艺《屋顶的问题儿童》中爆出的婚礼趣事,连刘在石、权志龙这样的顶级明星都成了背景板,真正的焦点竟然是至亲南昶熙送的礼金!据韩国媒体4月11日报道,知名艺人曹世镐分享了
苏州发布公积金贷款新政,符合条件家庭额度最高上浮40%,5月15日起实施 | 快讯
文/李贝贝4月17日下午,为更好地满足缴存人住房需求,支持多子女家庭合理住房需求,适应人民群众高品质居住需要,苏州市制定出台了《关于进一步加大公积金贷款支持力度的通知》(下称《通知》)。《通知》规定,养育未成年二孩的缴存人家庭
相关文章
推荐文章
发表评论
0评