聊聊Redis三大场景:缓存击穿、缓存穿透、缓存雪崩

疑问

相信很多同学在学习Redis的时候,会发现它不就是个键值对存储吗?功能就是缓存数据,为什么会遇到这么多情况?其实作者也有过这种想法,但是在深入学习了缓存击穿,穿透,雪崩这三种情况之后,相信你也会有不一样的理解。

什么是Redis缓存功能

首先,redis作为核心的缓存组件,其功能性是毋庸置疑的,但是很多同学做的都是小项目,没有那么大的并发量,此时缓存的效果和作用就没那么明显了。问题就在于怎么样去解决这种知行无法合一的状态,我觉得根本在于去假设自己的情形,人脑是具有幻想功能的。

背景

现在假设你是一个厨师,要给餐厅来吃饭的人做饭,那么首先热门菜的做法你是一定要会的,或者说你要有自己的招牌,就像那个菜单上被放大的图片和文字,总有几家店是有那么几道菜特别美味的,有几道就不那么美味。所以代入道数据库中,经常被查询的数据,我们也需要把它们熟记于心,而怎么做到快速访问到已查询数据?关键一定是缓存技术。

而Redis就相当于是我们的心脏部分,能记住的空间就那么多,肯定是要用来记住经常访问的,而且这个情况是跟人脑记忆部分很像的。就拿我们记住知识或者事物来举例子,如果一个东西你一直接触,那肯定是特别熟悉,特别快能想起来的。而如果一个东西比如考试,你只需要应付考试,记这一次就够了,再说了,再多也记不住啊。

那缓存也是一个道理,记住我们的目的,就是要存储经常要的数据。这也就引出一个热点key的问题,而那些不常用的key我们就经常清除。redis里面的清除机制符合我们遗忘的特性,用的多我就设成热点key,用得少我就把存活时间设置少一点。这样就促成了整个缓存系统和数据库的协调默契配合。


场景问题

而三大场景问题之一,或者说它们三个都是建立在这种前提下的。大家应该想到了,我说道Redis中首先是有缓存的,还有热点key和不热点key,也就是普通key,再结合它会被缓存清除,那么就有一个疑问了,如果热点key被清除呢,缓存还能不能继续工作?答案是肯定的否定,当然不能,如果作为头牌经常被访问的热点key都被删了,那么这个餐馆(缓存)肯定是开不下去的,为什么?因为它已经失去了它的作用了。除非说这个餐馆要改菜,换厨师,那它的招牌肯定也是要变的,除此之外,都会引发巨大的问题,假如一个厨师突然忘了他会的菜,就遭了。

缓存击穿

理解问题要形象化,尤其当我向别人输出的时候,缓存也是一样,要有一个具体的key被命中,才能访问具体的缓存数据,如果这个key没被命中,只有两种结果,厨子不会做是吧,那我就找店长啊,当redis失效,如果此时没有备用方案,那么请求就是直接找到数据库的,一两个人还好,如果这个量一大,那数据库绝对是会崩溃的。所以,现在我告诉你这个问题就是redis击穿,你肯定就理解了。当热点key失效,大量访问直指数据库,数据库崩溃。这就是缓存击穿

而在理解了缓存模型以后,其他两种情况就更简单了。

缓存雪崩

类比一下就是,大量缓存被清除的时候,也就是厨子们都休息的时候,这时候来很多客人,餐厅也是吃不消的,实际情况不会出现这种情况,大家看到人满了,就换一家呗。

也就是说如果redis有集群呢?大量数据就可以分散,那么数据库也就不会崩了。而这种大量数据被清除,同时大量申请访问缓存数据请求涌入数据库导致数据库崩溃的情况,也就是缓存雪崩

缓存穿透

最后一种缓存穿透,就像是来捣乱的人,什么意思呢?你开一家餐馆,一个人冲进来说:“我要点皮鞋炒肉”,那你会先笑一下,然后拿棒子把他打出门去,或者你都不敢打,万一是神经病呢?

缓存穿透也是一样的道理,你数据库和缓存建的好好的,比如所有主键都是正数,来个请求key就要访问-1.那这不是无理取闹吗?所以大量缓存穿透时数据库也是被搞得崩溃,心烦意乱的。


解决方案

这三种情况都是出现了对应的问题,既然是问题,肯定有解决方案的,而我相信你们理解了这种情况,自己都会解决了,只不过是相关一些手段和技巧在缓存时是有对应的专业名词,而其本质是最重要的。

针对击穿

应对击穿,我们不能轻易删除热点key,或者说项目组商量商量,什么时候删,多久删一次,不管效果如何大家一起承担。这是不是很合理。就像一家餐厅,什么是换招牌菜,都是要慎重考虑的,一般都是不换,在此基础上发展其他菜系,逐步过渡才是合理的。

针对穿透

应对穿透,我们在门口设置保安(上层的过滤器,布隆过滤器啊等等),或者说内部检查(业务层的参数检验,最好每一层都要有,这就好比说一个傻子进来点菜,点个皮带炒肉,在旁边站着的服务员一看,皮带炒肉,我抄你还差不多,看看什么情况,要是认真的,我去你的,直接给赶出去了。要么就是说厨子做之前看一下,那废话,皮带炒肉他做的出来吗),在门口挂牌子,有这种搅乱生意的人进来,我们就赶走他,或者不让他点菜,这样就不会累坏厨子了是不是?

针对雪崩

应对雪崩,这都不需要应对,就怕爱吃这家菜的人多,重大节日什么的,特别多访问请求涌过来,就指着这家店,那老板娘肯定是乐开了花,但是问题忙不过来啊,怎么办,开连锁呗(redis集群,开十家够不),要么就是多招几个厨子呗(主从+哨兵,主从就是俩厨子,一个厨子做累了就休息,换另一个,万一俩厨子交替都忙不过来呢?来个小二提醒老板娘,主从出事了,该解决了,要不然忙起来老板娘顾不上,最后一直在那点菜,客人吃不到不得气坏吗,意思就是这时候重大事情,要及时解决问题,否则会有很严重后果,比如很多人一看服务器崩了,那就换别的家了,就提供不了服务挣不到钱了)


优化缓存

所以,当我们使用redis时,应该怎么做才能开好一家饭店?

一、减少Redis压力,降低缓存依赖

减少对缓存的依赖,既然热点数据这么关键,那加上本地缓存(用本地HashMap都可以,我用的ConCurrentHashMap),存在本地不就好了,又能提高性能又能减少redis压力,一举两得。也就是说提前准备好,防止供应不上。

二、提高Redis可用性

像我前面说的,主从加哨兵,要么就连锁(集群)。钱是肯定能挣到的。那你要考虑有没有这么多钱,有成本的,对吧。

三、下层业务降级限流

提前准备备用方案,什么叫备用方案,核心就是你提供不了这么大数据,在上这么多道菜的同时保证这么快的上菜速度,那就让大家等呗,访问量大的时候大家又不是不知道,就算他不知道你给他提醒,或者说给个提示就行了。所以,想好备用方案,就像那个老板娘,限流,什么是限流,店里全是人,那我肯定一次就能做那么多菜,速度是只能快一点点的,所以我给每桌差不多的上,上了你先吃,然后我催着把相同的菜同时多做,一锅炒出来,这是不是都是方法啊。所以备用方案就是这样,当业务崩的时候,你提前想好了怎么去解决,而且设计好了,那不就不怕了。而且数据库不仅提供你这一家服务,不能说你这桌要的菜多了,我其他桌就不做了,就只做你这一桌,所以要限流,不能因为你要多的就给你做的快,慢慢等呗,一会儿上一道,人也不会急的,只要别太慢。


总结

聊到这,我相信很多同学已经明白了,所谓保护数据库其实就是好好经营一个小饭店,别让厨子累着了,累瘫了,崩溃了。而redis作为关键的缓存,减少访问数据库量的次数是提高性能的关键。

如何让厨子舒服的做菜,拿尽可能最少的工资,这是老板娘需要考虑的。

如何让数据库出最少的力,干最多的活,这是我们代码人需要考虑的。

所以,你懂了吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值