前言
作为后端开发工程师,不管是在工作中,还是面试交谈中,只要涉及到Redis,或者缓存的问题,绝对必不开的问题,那就是缓存穿透了。这篇文章主要讲解为什么会出现缓存击穿。本文的缓存以Redis为例,其余的中间价,解决方案的思想一样,个别Api可能不一致。
产生原因
首先缓存击穿的情况呢,一定是Redis当作缓存使用,而不是当数据库使用,如果当数据库使用的话,是没有这样的问题存在的。
这里以掘金的一个抽奖例子为例吧。
假设一下,围观大奖这一块的数据,为了减少数据库压力,可以不可以放到缓存中。如果用户请求,通过缓存拿到列表返回这个数据。
那么这个时候会有一个问题,既然是缓存,他肯定是有一个过期时间的。那么在这个时候,恰巧就那么巧有大量的流量来请求这个接口,那这个时候缓存都没有了,那最后还是会去请求数据库去获取数据,那么称这个现象呢,就叫缓存穿透。
解决办法
那这个时候会有人想,既然问题的产生原因是过期时间。那不给他过期时间是不是就可以了。如果是这个情况是在业务中产生的话,那确实可以了。
但是会产生一个问题,后台数据如果更新了,怎么去更新redis中的缓存。还有就是,如果这个缓存特别大,那是不是占用了特别大的Redis空间呢,这个方法不可取。
那么具体怎么做呢?先来看一张图
这个业务的大概的逻辑是这样的。我们仅需要对这个部分的业务代码进行一点改动。
在上图贴出了要改动的点,具体讲解一下.
- 第一步 还是从redis中获取数据
- 第二步 如果redis中拿到的是null,这里做了个操作,setnx(lock, true)
- 首先要说一下setnx是什么意思,全称(set if not exists)看字面意思可以看出来,不存在的时候插入。
- 这里的加这句话的意思呢,就是表明,已经有人去查寻数据库了,后面的就不要查了,你在那里等着就行。我查到了会重新塞回去的。
- 第三步 查询数据库,放入缓存,把锁设置取消,然后返回前端。
话题延伸
这里留一个互动的小思考题,就是我上方的文章中有提到过的,如果数据库有更新,怎么做可以把缓存也更新,保证一致性。
有好的方案欢迎在评论区交流,这篇文章比较简单,就先这样了。
都看到这了,不点个赞再走吗🤪