《吊打面试官》系列-缓存雪崩、击穿、穿透

你知道的越多,你不知道的越多java

点赞再看,养成习惯程序员

前言

Redis在互联网技术存储方面使用如此普遍,几乎全部的后端技术面试官都要在Redis的使用和原理方面对小伙伴们进行360°的刁难。做为一个在互联网公司面一次拿一次offer的面霸(请容许我使用一下夸张的修辞手法),战胜了无数竞争对手,每次都只能看到无数落寞的身影失望的离开,略感愧疚,在一个寂寞难耐的夜晚,我痛定思痛,决定开始写《吊打面试官》系列,但愿能帮助各位读者之后面试势如破竹,对面试官进行360°的反击,吊打问你的面试官,让一同面试的同僚瞠目结舌,疯狂收割大厂offer!web

一点感慨

原本都把稿子放到公众号保存了,洗澡的时候想了一下晚上的比赛,以为仍是打开电脑写点东西,跟文章内容不要紧,只是一点我的的感慨,不知道多少小伙伴看了昨天SKT VS G2的比赛,又不知道多少小伙伴还记得Faker手抖的那一幕。面试

不知道大家看了是什么感觉,我看到他手抖的时候我心里也抖了,世界赛我支持的都是LPL的队伍,可是我喜欢李哥这我的,那种对胜利的执著,这么多年了那种坚持本身的坚持,这么多利益诱惑在面前却只想要胜利,这样的人我好喜欢啊,我想不少人也喜欢。redis

可能就像不少网友说的那样,英雄迟暮,可是我以为他仍是有点东西,就像不少人说咱们程序员只能吃年轻饭同样,可是若是你坚持本身的坚持,作个腹有诗书气自华的仔,我想最后确定会获得本身的获得。算法

好了我也不煽情了,咱们开始讲技术吧。数据库

正文

上一期吊打系列咱们提到了Redis的基础知识,还没看的小伙伴能够回顾一下 后端

《吊打面试官》系列-Redis基础缓存

那提到Redis我相信各位在面试,或者实际开发过程当中对缓存雪崩穿透击穿也不陌生吧,就算没遇到过可是你确定听过,那三者到底有什么区别,咱们又应该怎么去防止这样的状况发生呢,咱们有请下一位受害者。安全

面试开始

一个大腹便便,穿着格子衬衣的中年男子,拿着一个尽是划痕的mac向你走来,看着快秃顶的头发,心想着确定是尼玛顶级架构师吧!可是咱们腹有诗书气自华,虚都不虚。

小伙子我看你的简历上写到了Redis,那么咱们直接开门见山,直接怼常见的几个大问题,Redis雪崩了解么?

帅气迷人的面试官您好,我了解的,目前电商首页以及热点数据都会去作缓存 ,通常缓存都是定时任务去刷新,或者是查不到以后去更新的,定时任务刷新就有一个问题。

举个简单的例子:若是全部首页的Key失效时间都是12小时,中午12点刷新的,我零点有个秒杀活动大量用户涌入,假设当时每秒 6000 个请求,原本缓存在能够扛住每秒 5000 个请求,可是缓存当时全部的Key都失效了。此时 1 秒 6000 个请求所有落数据库,数据库必然扛不住,它会报一下警,真实状况可能DBA都没反应过来就直接挂了。此时,若是没用什么特别的方案来处理这个故障,DBA 很着急,重启数据库,可是数据库立马又被新的流量给打死了。这就是我理解的缓存雪崩。

我刻意看了下我作过的项目感受再吊的都不容许这么大的QPS直接打DB去,不过没慢SQL加上分库,大表分表可能还还算能顶,可是跟用了Redis的差距仍是很大

同一时间大面积失效,那一瞬间Redis跟没有同样,那这个数量级别的请求直接打到数据库几乎是灾难性的,你想一想若是打挂的是一个用户服务的库,那其余依赖他的库全部的接口几乎都会报错,若是没作熔断等策略基本上就是瞬间挂一片的节奏,你怎么重启用户都会把你打挂,等你能重启的时候,用户早就睡觉去了,而且对你的产品失去了信心,什么垃圾产品。

面试官摸了摸本身的头发,嗯还不错,那这种状况咋整?你都是怎么去应对的?

处理缓存雪崩简单,在批量往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在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个无缺无损的桶上凿开了一个洞。

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

缓存穿透我会在接口层增长校验,好比用户鉴权校验,参数作校验,不合法的参数直接代码Return,好比:id 作基础校验,id <=0的直接拦截等。

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

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

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

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

那你还有别的办法么?

还有我记得Redis还有一个高级用法布隆过滤器(Bloom Filter)这个也能很好的防止缓存穿透的发生,他的原理也很简单就是利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就行了,存在你就去查了DB刷新KV再return。

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

缓存击穿的话,设置热点数据永远不过时。或者加上互斥锁就能搞定了
做为暖男,代码我确定帮大家准备好了

面试结束

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

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

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

暗示点赞,每次都看了不点赞,大家想白嫖我么?大家好坏喲,不过我喜欢

总结

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

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

你们必定要理解是怎么发生的,以及是怎么去避免的,发生以后又怎么去抢救,你能够不是知道很深刻,可是你不能一点都不去想,面试有时候不必定是对知识面的拷问,或许是对你的态度的拷问,若是你思路清晰,而后知其然还知其因此然那就很赞,还知道怎么预防那来上班吧。

最后暖男我继续给大家作个小的技术总结:

通常避免以上状况发生咱们从三个时间段去分析下:

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

  • 事中:本地 ehcache 缓存 + Hystrix 限流+降级,避免** MySQL** 被打死。

  • 过后:Redis 持久化 RDB+AOF,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。

上面的几点我会在吊打系列Redis篇所有讲一下这个月应该能够吧Redis更完,限流组件,能够设置每秒的请求,有多少能经过组件,剩余的未经过的请求,怎么办?走降级!能够返回一些默认的值,或者友情提示,或者空白的值。

好处:

数据库绝对不会死,限流组件确保了每秒只有多少个请求能经过。 只要数据库不死,就是说,对用户来讲,3/5 的请求都是能够被处理的。 只要有 3/5 的请求能够被处理,就意味着你的系统没死,对用户来讲,可能就是点击几回刷不出来页面,可是多点几回,就能够刷出来一次。

这个在目前主流的互联网大厂里面是最多见的,你是否是好奇,某明星爆出什么事情,你发现你去微博怎么刷都空白界面,可是有的人又直接进了,你多刷几回也出来了,如今知道了吧,那是作了降级,牺牲部分用户的体验换来服务器的安全,可还行?

说到服务器,最近双十一,阿里云的服务器对新用户很友好(老用户悄悄用爸妈手机注册),贼便宜!

经过个人连接购买,一年最低仅需86块(新用户专享,若是不是新用户的能够用家里人的帐号购买),80一年,200三年我以为跟白嫖差很少,我直接用老妈帐号买了三年的,准备搭建一个小项目玩玩。你们能够买来玩玩,想看服务器文章的朋友留言给我,能够的话我会写一期怎么利用服务器的文章。

点个人连接去买有优惠哟

好了各位,以上就是这篇文章的所有内容了,我后面会每周都更新几篇《吊打面试官》系列和Java技术栈相关的文章。若是你有什么想知道的,也能够留言给我,我一有时间就会写出来,咱们共同进步。

很是感谢您能看到这里,若是这个文章写得还不错的话 求点赞 求关注 求分享 求留言 (对我很是有用)各位的支持和承认,就是我创做的最大动力,咱们下篇文章见!

敖丙 | 文 【原创】


每周都会持续更新《吊打面试官》系列能够关注个人公众号 JavaFamily 第一时间阅读,也会有朋友一线大厂的内推机会不按期推出(字节跳动,阿里,网易,PDD,滴滴,蘑菇街等),就业和工做上有什么问题也能够直接滴滴我,我也是个新人,不过不影响咱们一块儿进步,做为渣男,我给不了你工做,还给不了你温暖嘛?

相关文章
相关标签/搜索