Redis 缓存击穿 &穿透&雪崩
下面讨论的击穿 &穿透&雪崩 都是基于Redis key 没有命中,同一时间是高并发的请求,然后对数据库造成大量请求;
Redis 作为缓存的执行流程
客户端发起请求,若数据有在Redis 做缓存,则先去Redis 查询,如果没有获取到缓存,则去数据获取数据,获取到数据后,更新数据到Redis;
都发生了下面的事情
1.缓存击穿
Redis 的 key 失效,或者在Redis 中被淘汰;
key 在Redis 缓存中没有,所有的查询去查询数据库;
解决:
获取不到数据的时候 (获取数据库数据的时候加一个分布式锁 ,锁时key)
- 设置锁 setnx 对key锁 设置过期时间 ( 防止有锁的线程 阻塞或者宕机) ,
- get key
- 设置成功的才可以访问数据库,处理业务 (锁时间到了但是不能给其他线程获取到线程,第二个来,再起一个线程,不断的对key 续约);
- 其他的线程等待( sleep )锁 处于一直setnx 的步骤 直到成功;
2.缓存穿透
Redis 的 key 在Redis 和数据库中都不存在,或者在Redis 中被淘汰;每次请求都走数据库查询
解决:布隆过滤器
3.缓存雪崩
同一时间段,大量的数据过期或者被淘汰;导致大量的数据请求直接到数据库;
解决:设置随机的过期,尽量不要设置key 同一时间过期(过期时间与时间无关);或者业务层在该时间点判断休息延时一会儿,等待缓存数据加载后查询缓存;