缓存穿透 缓存击穿 缓存雪崩 这三者是什么 如何处理

通常我们使用缓存中间件的方式 将数据库的热点数据缓存到Redis中 尽量去缓存中查找数据,目的就是为了减轻数据库的压力

缓存穿透 缓存击穿 缓存雪崩 这三者是什么 如何处理_第1张图片

那什么是 缓存穿透,缓存击穿 与 缓存雪崩 呢 ?

缓存穿透

当Redis中不存在某个key时,将对数据库进行查询操作 但如果数据库也不存在 就会造成每一个请求即查询redis也会查询数据库 这就是缓存穿透

缓存穿透 缓存击穿 缓存雪崩 这三者是什么 如何处理_第2张图片

比如说一个查询接口 查询范围在 1~1000 但是遇到不怀好意的用户 大量请求 1000 ~ … 查询不存在的信息

将给数据库造成巨大的压力 并且Redis缓存形同虚设了

解决办法

一般处理办法有两种

方式一 : 利用布隆过滤器 首先将Redis中的key全部添加到布隆过滤器中 布隆过滤器判断不存在的一定Redis中也没有 可以过滤掉绝大部分恶意请求 但是 布隆过滤器不是百分百正确的 判断有的 可能redis中也不存在

方式二: 缓存空值

当从数据库中没有查询到数据的时候,也给redis中缓存一个空值 并且返回这个空值 这样下次同样信息的请求过来时,redis就能直接处理不用再去查询数据库了

缓存击穿

当某一个时刻 redis中某一个 热点 Key 过期,大量的并发请求打到数据库上 可能造成数据库崩溃 打在一个点上 这就是缓存击穿

缓存击穿 与 缓存穿透的区别在于 缓存击穿是Redis中过期,数据库中有 而 缓存穿透是Redis中没有,数据库中也没有

缓存穿透 缓存击穿 缓存雪崩 这三者是什么 如何处理_第3张图片

缓存击穿最大的问题在于大量请求发现Redis中的数据找不到了,要去数据库中查找,而数据库中是有数据的 所以我们只需要控制请求数

放一个请求去查询数据库,查到数据后,将数据写回 Redis 此时再放其他请求去查询Redis , 此时Redis已经有了相应的数据

解决办法

加分布式锁 可以使用 Redis 或者 Mysql 都行 Redis做分布式锁相对简单

判读key是否存在,不存在则创建key,value,同时设置过期时间,防止死锁 要保证原子性 调用 setIfAbsent 方法

 //原子操作 设置 UUID 与 过期时间 30 秒
            Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(RedisConst.SKUKEY_LOCK + skuId, uuid, 30, TimeUnit.SECONDS);

key 设置前缀和标识 value设置成锁持有者的唯一标识 防止锁过期后误删其他线程的锁

缓存雪崩

缓存雪崩 同一时间Redis中大量热点key过期 造成数据库处理大量请求最后崩溃

相比缓存击穿 过期的热点key数量更多

解决办法

设置热点key过期时间时,添加一个随机值 避免同一时间过期

你可能感兴趣的:(Redis,缓存,redis,数据库)