一、Redis作为一个缓存中间件是如何工作的?
架构图如下
![](https://i-blog.csdnimg.cn/blog_migrate/293d56d5f8915d8f860d12091d5ac8d7.png)
过程如下
客户端发起一个查询请求的时候,首先去缓存中查询,如果数据在缓存中存在,则直接将缓存中数据返回给客户端;如果数据在缓存中不存在,则继续查询数据库,若数据库在数据库中存在,则直接将数据放入缓存中并返回给客户端。如果在数据库中也不存在,则直接返回null给客户端。
缓存穿透
定义
指查询一个缓存中和数据库中都不存在的数据,导致每次都会透过缓存,直接查库,最后返回空。
用户发起多次请求这条不存在的数据时,对数据库造成的压力就非常大。
![](https://i-blog.csdnimg.cn/blog_migrate/c5469e84fb8ea8ad638d35cbb3e27103.png)
解决方案
(1)缓存空对象
当数据库中查不到数据时,我缓存了一个空对象,给这个空对象的缓存设置一个过期时间,这样下次再查询该数据时候,就可以直接从缓存中拿到,从而减小数据库压力的目的。
(2)使用布隆过滤器
缓存击穿
定义
当缓存中某个热点数据过期了,在热点数据重新载入缓存之前,有大量的查询请求穿过缓存,直接查询数据库。导致数据库压力骤增,造成大量请求阻塞,甚至直接挂掉。
![](https://i-blog.csdnimg.cn/blog_migrate/4ea445f08d748ff71f8e14a397b609d5.png)
解决方案
(1)设置key永不过期
(2)使用分布锁
锁的对象时key,这样查询同一个key的请求并发进来时,只有一个请求获取到锁,获取到锁的线程查询数据库,将查询到结果放入缓存中,然后释放锁,此时锁等待的请求即可继续执行,由于缓存中已经存在数据,故直接获取数据返回,并不会查询数据库。
![](https://i-blog.csdnimg.cn/blog_migrate/8b2cd2ed4fe63934e1aa55ba61e40594.png)
缓存雪崩
定义
当缓存中大量的key在同一时刻过期,或者Redis直接宕机,导致大量的查询请求全部到达数据库,造成数据库查询压力骤增,甚至直接挂掉。
![](https://i-blog.csdnimg.cn/blog_migrate/eed0e86f7f38443d26e9e2654fb34815.png)
解决问题
(1)打散每个key的过期时间
(2)redis高可用方案部署
l如: 主从、哨兵、Redis集群