前言:
我们知道一般软件的数据都是保存在磁盘中的,但是磁盘的读写是计算机里面最慢的硬件了,所以当并发量很高时会严重影响用户体验,甚至于会导致数据库崩溃,所以人们一般会在客户端与数据库之间增加Redis作为缓存,因为Redis是内存数据库所以能大大提高系统性能。但是在实际应用中会存在缓存异常:穿透、击穿、雪崩。那么他们分别是什么,为什么会产生,又怎么解决呢?那就让我们跟着咱奶奶一起学习吧!!
一、缓存穿透
1. 什么是缓存穿透?
想象你开了一个杂货铺,货架上摆满零食(缓存),仓库里还有更多库存(数据库)。
正常情况:客人想买薯片,先看货架(缓存),有就直接买走;没有的话,你再去仓库(数据库)拿。
缓存穿透: 一群调皮小孩天天来问:“有没有猪猪侠的超级棒棒糖老板!?”(缓存和数据库里面都没有的数据) 你每次都要跑仓库找,但仓库根本没有这东西! 结果:你累得半死(数据库压力大),真正想买零食的客人却被耽误了(服务变慢或崩溃)。
2. 你该怎么样解决这些头痛的问题呢?(缓存穿透解决方案)
① 布隆过滤器 → 杂货铺的货物清单
-
你把每次进的货记录在本子上(布隆过滤器),记录所有真正存在的零食(数据库存在的数据)。
-
小孩问“猪猪侠超级棒棒糖”时(恶意攻击,不存在数据等):
- 你先查清单,发现根本没这东西,直接说:“没有!滚蛋小屁孩!”(拦截无效请求)
- 只有清单上有的零食,你才去货架或仓库找。
-
缺点:万一把“新到的辣条”漏写在清单上(误判),可能让客人白跑一趟,但概率很低。
-
ps:为了让咱奶也可以听懂所以这里对布隆过滤器的介绍较为简单,但是像你我这种新时代的聪明绝顶的程序员怎么能如此,想要进一步学习的可以查看我的“关于布隆过滤器的实现原理”这篇文章。
② 缓存空对象 → 贴个“缺货”标签
- 第一次有人问“超级棒棒糖”,你去仓库找了一圈,确实没有。
- 于是你在货架上贴一张纸条:“超级棒棒糖——缺货!明天再来!”(在缓存中添加空值,但是得设置过期时间,否则空值越来越多会影响系统性能)
- 其他小孩再来问,你直接指纸条:“缺货!”(避免反复查询数据库)
③ 参数校验 → 拒绝离谱问题
- 你立个规矩:“只卖零食,不卖玩具、不卖家电!”(校验参数格式)
- 小孩问“你家卖冰箱吗?”你直接摆手:“不卖!别瞎问!”(拦截非法请求)
·
④ 限流熔断 → 让捣蛋鬼消停会儿
- 如果小孩一分钟内问了100次“有没有奥特曼饼干?”,你大吼:“再问就等10分钟!”(限流)
- 如果仓库忙不过来,你直接挂个牌子:“休息5分钟!”(熔断),先服务正常客人。
总结
- 问题:一群熊孩子问根本不存在的零食,害你跑断腿。
- 解决:
1️⃣ 提前记好所有零食清单,直接拒绝瞎问(布隆过滤器)。
2️⃣ 第一次找不到就贴“缺货”,省得再跑(缓存空对象)。
3️⃣ 不回答离谱问题,比如“卖不卖汽车?”(参数校验)。
4️⃣ 熊孩子问太多就让他闭嘴一会儿(限流熔断)。
最终效果:你轻松卖零食,熊孩子捣不了乱!🍿🚫