情景再现,Java 面试老大难问题:缓存雪崩,穿透,击穿,一文道明

处理缓存雪崩简单,在批量往 Redis 存数据的时候,把每个 Key 的失效时间都加个随机值就好了,这样可以保证数据不会在同一时间大面积失效,我相信,Redis 这点流量还是顶得住的。

setRedis(Key,value,time + Math.random() * 10000);

复制代码

如果 Redis 是集群部署,将热点数据均匀分布在不同的 Redis 库中也能避免全部失效的问题,不过本渣我在生产环境中操作集群的时候,单个服务都是对应的单个 Redis 分片,是为了方便数据的管理,但是也同样有了可能会失效这样的弊端,失效时间随机是个好策略。

或者设置热点数据永远不过期,有更新操作就更新缓存就好了(比如运维更新了首页商品,那你刷下缓存就完事了,不要设置过期时间),电商首页的数据也可以用这个操作,保险。

那你了解缓存穿透和击穿么,可以说说他们跟雪崩的区别么?

===========================

嗯,了解,我先说一下缓存穿透吧,缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,我们数据库的 id 都是 1 开始自增上去的,如发起为 id 值为 -1 的数据或 id 为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大,严重会击垮数据库。

小点的单机系统,基本上用 postman 就能搞死,比如我自己买的阿里云服务

像这种你如果不对参数做校验,数据库 id 都是大于 0 的,我一直用小于 0 的参数去请求你,每次都能绕开 Redis 直接打到数据库,数据库也查不到,每次都这样,并发高点就容易崩掉了。

至于缓存击穿嘛,这个跟缓存雪崩有点像,但是又有一点不一样,缓存雪崩是因为大面积的缓存失效,打崩了 DB,而缓存击穿不同的是缓存击穿是指一个 Key 非常热点,在不停地扛着大并发,大并发集中对这一个点进行访问,当这个 Key 在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。

面试官露出欣慰的眼光,那他们分别怎么解决

====================

缓存穿透我会在接口层增加校验,比如参数白名单、用户鉴权、参数校验,不合法的参数直接拒绝,比如:id 做基础校验,id <=0 的直接拦截等。

这里我想提的一点就是,我们在开发程序的时候都要有一颗“不信任”的心,就是不要相信任何调用方,比如你提供了 API 接口出去,你有这几个参数,那我觉得作为被调用方,任何可能的参数情况都应该被考虑到,做校验,因为你不相信调用你的人,你不知道他会传什么参数给你。

举个简单的例子,你这个接口是分页查询的,但是你没对分页参数的大小做限制,调用的人万一一口气查 Integer.MAX_VALUE 一次请求就要你几秒,多几个并发你不就挂了么?是公司同事调用还好大不了发现了改掉,但是如果是黑客或者竞争对手呢?在你双十一当天就调你这个接口会发生什么,就不用我说了吧。这是之前的 Leader 跟我说的,我觉得大家也都应该了解下。

从缓存取不到的数据,在数据库中也没有取到,这时也可以将对应 Key 的 Value 对写为 null、位置错误、稍后重试这样的值具体取啥问产品,或者看具体的场景,缓存有效时间可以设置短点,如 30 秒(设置太长会导致正常情况也没法使用)。

这样可以防止攻击用户反复用同一个 id 暴力攻击,但是我们要知道正常用户是不会在单秒内发起这么多次请求的,那网关层 Nginx 本渣我也记得有配置项,可以让运维大大对单个 IP 每秒访问次数超出阈值的 IP 都拉黑。

那你还有别的办法么?

==========

那 Redis 作 key-value 存储,命中 key 返回相应 valu, 不存在的 key,直接拒绝, 这是最简单靠谱的方式。

当然,如果不能作存储,比如容量不够等,这里还有一个方法:Redis 还有一个高级用法布隆过滤器(Bloom Filter)这个也能很好地防止缓存穿透的发生,他的原理也很简单就是利用高效的数据结构和算法快速判断出你这个 Key 是否在数据库中存在,不存在你 return 就好了,存在你就去查了 DB 刷新 KV 再 return。

那又有小伙伴说了如果黑客有很多个 IP 同时发起攻击呢?这点我一直也不是很想得通,但是一般级别的黑客没这么多肉鸡,再者正常级别的 Redis 集群都能抗住这种级别的访问的,小公司我想他们不会感兴趣的。把系统的高可用做好了,集群还是很能顶的。

缓存击穿的话,设置热点数据永远不过期。或者加上互斥锁就能搞定了

作为暖男,代码我肯定帮你们准备好了

面试结束

====

嗯嗯还不错,三个点都回答得很好,今天也不早了,面试就先到这里,明天你再过来二面我继续问一下你关于 Redis 集群高可用,主从同步,哨兵等知识点的问题。

晕居然还有下一轮面试!(强行下一期的伏笔哈哈)但是为了 offer 还是得舔,嗯嗯,好的帅气面试官。

能回答得这么全面这么细节还是忍不住点赞

(暗示点赞,每次都看了不点赞,你们想白嫖我么?你们好坏喲,不过我喜欢)

总结

==

我们玩归玩,闹归闹,别拿面试开玩笑。

本文简单的介绍了,Redis 的雪崩,击穿,穿透,三者其实都差不多,但是又有一些区别,在面试中其实这是问到缓存必问的,大家不要把三者搞混了,因为缓存雪崩、穿透和击穿,是缓存最大的问题,要么不出现,一旦出现就是致命性的问题,所以面试官一定会问你。

大家一定要理解是怎么发生的,以及是怎么去避免的,发生之后又怎么去抢救,你可以不是知道很深入,但是你不能一点都不去想,面试有时候不一定是对知识面的拷问,或许是对你的态度的拷问,如果你思路清晰,然后知其然还知其所以然那就很赞,还知道怎么预防那来上班吧。

最后给你们做个小的技术总结:

一般避免以上情况发生我们从三个时间段去分析下:

  • 事前:Redis 高可用,主从+哨兵,Redis cluster,避免全盘崩溃。

最后

给大家送一个小福利

附高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、准备面试跳槽、自身职业规划迷茫的朋友们。

给大家送一个小福利

[外链图片转存中…(img-g6ogQs5E-1721188301473)]

附高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、准备面试跳槽、自身职业规划迷茫的朋友们。

[外链图片转存中…(img-AJCi66zO-1721188301474)]

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值