1、redis穿透
原因
穿透的意思,我们穿过redis直接查询数据库,发现数据库也没有值,透过redis和数据库。
需要达到效果
发现数据没有值的时候我们就不要再查数据,拦截这种无效的请求,给数据库带来的压力。
场景
1、 你不知道请求是不是并发。
2、 保证DB的压力,进行有效的响应。
解决方法
1、使用布隆过滤器,初始化所有key到redis中。(相对复杂点)
2、我们加锁也可解决这个问题。
加锁过程
查询的对应key的数据之前,先获得锁,如果锁被占用了就等待释放锁。获得锁,就去查询数据库,发现数据是空,就添加的一个空值标记,然后释放锁。等待的业务发现是空值就不再查询数据库,直接返回。
流程
1、请求redis,肯定没有。
2、大家抢锁(只发生在redis取不到值的情况下)
2.1 抢到锁的去查DB O(1)
2.2、没有抢到就sleep
3、查DB的更新redis o(1)
4、sleep的进程回到第一步。
击穿
原因
热点key过期(没有被缓存)数据库有数据,而且有大量并发redis没有缓存。
解决方法
加锁、线程等待,不要让请求直接打到DB.
雪崩
原因
key的数量是N,并且一起过期,数据库有数据,大量的并发请求,redis没有缓存。
解决方法
单个key加锁,请求redis的查询进行流量限制加锁,线程等待。
流量限制锁
我们用zset存储时间戳,只要总大于界限值就进行等待。
限流代码
具体步骤:
1、 删除大于当前时间1秒的数据。
2、 判断剩下set的size是否大于限定值。大于就直接的返回限流。
3、 不大于就插入当前时间戳到zset 中。
如果使用的是redis集群就需要在限流前面加锁排他锁。