一、缓存穿透
1. 原因
太多请求在redis查不到,转而直接查询数据库,导致redis击穿
先去查询redis,如果有就用redis
如果redis没有,查询mysql
a. 查询某个数据,redis中没有,查询mysql
b. 多个客户端查询这个数据,都会查询mysql
c. 太多的mysql查询, redis都没起到作用, redis被穿透了, mysql压力太大
d. 一个服务的mysql挂了,导致一个服务不可用,然后再引发微服务的雪崩
2. 解决方案
2.1 缓存空对象
1 . 如果在redis和mysql都查不到数据,则返回一个空对象
2 . 同时将该空对象在redis中进行缓存,并设置过期时间
3 . 后续查询的时候就会在redis中找到结果,避免了缓存穿透
2.2 步隆过滤器
二、缓存击穿
1. 原因
假如刚好某个key过期,查询这个key的请求过多,短时间都去查询数据库
1 . 某个事件, 在mysql中查到后,保存在redis中并设置一定的过期时间
2 . 假如60s过期, 在随后的0.1s中刚好点击量很多,海量查询会直接去mysql查询
3 . 虽然0.1s 内,一次查询mysql成功,就可以保存在redis中,但是mysql可能直接挂了
2. 解决方案
2.1 热点数据不过期
2.2 加锁互斥
查询mysql时,只允许一个redis线程查询 所有请求基本都是去查询redis的,只有一个是用来查询mysql的
三、缓存雪崩
1. 原因
波峰压力导致mysql挂了 redis宕机造成服务不可用
1 . 双11 12 点开始,所有缓存数据过期时间1h
2 . 1 点后,所有商品的缓存都失效
3 . 1 点后1秒内,大量的查询到达mysql,导致mysql压垮
1 . redis突然宕机
2. 解决方案
2.1 异地多活
2.2 限流降级
用同一个redis的多个服务,对部分服务进行限流降级
2.3 数据预热
在大流量访问时,预先加载可能访问到的所有到redis中,并设置不同的过期时间