处理缓存雪崩简单,在批量往 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 还是得舔,嗯嗯,好的帅气面试官。
能回答得这么全面这么细节还是忍不住点赞
(暗示点赞,每次都看了不点赞,你们想白嫖我么?你们好坏喲,不过我喜欢)
总结
==
最后
即使是面试跳槽,那也是一个学习的过程。只有全面的复习,才能让我们更好的充实自己,武装自己,为自己的面试之路不再坎坷!今天就给大家分享一个Github上全面的Java面试题大全,就是这份面试大全助我拿下大厂Offer,月薪提至30K!
我也是第一时间分享出来给大家,希望可以帮助大家都能去往自己心仪的大厂!为金三银四做准备!
一共有20个知识点专题,分别是:
Dubbo面试专题
JVM面试专题
Java并发面试专题
Kafka面试专题
MongDB面试专题
MyBatis面试专题
MySQL面试专题
Netty面试专题
RabbitMQ面试专题
Redis面试专题
Spring Cloud面试专题
SpringBoot面试专题
zookeeper面试专题
常见面试算法题汇总专题
计算机网络基础专题
设计模式专题
gv3N6-1714703780900)]
常见面试算法题汇总专题
[外链图片转存中…(img-9qBvqWDB-1714703780900)]
计算机网络基础专题
[外链图片转存中…(img-UOUmM7mO-1714703780900)]
设计模式专题
[外链图片转存中…(img-zCwRHw1A-1714703780901)]