目录
一、缓存穿透
定义:
缓存穿透是指用户发送查询请求,在缓存中没有拿到数据,于是就去数据库中查询,发现数据库中也没有。数据库也没有数据存到缓存中,当大量请求同时查询数据库时,就会导致缓存穿透。
解决方案:
1、可以设置一个null值存到缓存中,这样查询到这个key时就会返回一个null。
优点:代码维护简单。
缺点:这样会占内存,因此需要设置一个较短的失效时间,但是可能导致数据不一致。
2、可以设置一个布隆过滤器,首先判断有没有这个key,有的话再从缓存中查。
原理:
- 初始状态时,BloomFilter是一个长度为m的位数组,每一位置都为0。
- 添加元素x时,x使用k个hash函数得到k个hash值,对m取余,对应的bit位设置为1。
- 判断y是否属于这个集合,对y使用k个哈希函数得到k个哈希值,对m取余,所有对应的位置都是1,则认为y属于该集合(哈希冲突,可能存在误判),否则就认为y不属于该集合。可以通过增加哈希函数和增加二进制位数组的长度来降低错报率。
优点:占用内存少。
缺点:但是这样有误判,一般我们可以设置误判率在5%就能满足实际需求。代码维护复杂。
二、缓存击穿
定义:
缓存击穿是指当用户查询数据时,查询过期的key时,缓存中没有数据,于是从数据库中查询,当大量并发查询发生时就会导致缓存击穿。
解决方案:
1.设置redis分布锁,一个线程执行时,发现key过期了,于是添加分布式锁,将数据库的数据更新到缓存中,第二个线程查询时,不会再添加分布式锁,于是进入休眠状态,等待第一个线程完成缓存释放锁,然后返回新数据。
2.当查询数据库往缓存中存数据时,增加一个逻辑过期,当用户进行查询操作时,一个线程首先判断是否逻辑过期,如果逻辑过期,再加一个线程更新缓存,原线程返回旧数据。
缺点:可能会导致数据不一致的问题。
三、缓存雪崩
定义:
缓存雪崩是指多个key同时过期时或者redis宕机,有大量查询发生,缓存中没有数据,就会去数据库中查询。
解决方案:
1.构建redis集群。
2.给key设置随机过期时间,让同一时间没有那么多key同时过期。
3.采用多级缓存:本地进程作为一级缓存,redis作为二级缓存,不同级别的缓设置超时时间不同,即使某个缓存过期了,那么也有其他级别的缓存兜底。