【Redis】大白话理解redis缓存穿透、缓存击穿、缓存雪崩及其解决方案

缓存穿透

缓存穿透有两种情况:
一种是查询的数据在数据库中存在,另一种是数据在数据库中不存在。

  • 第一种情况的缓存穿透出现在高并发场景下,要查询的数据还未被缓存到redis,我们期望的是,查询一次数据库,然后将数据写入缓存,但是高并发场景下,一下子进来成百上千个请求,我们将数据库数据写入缓存需要时间,在写入已经开始但还未完成时,就会有很多查询请求直接打到数据库上造成高并发场景下数据库的崩坏。
  • 第二种情况的缓存穿透指的是,数据在数据库中不存在。 代码逻辑是:得到查询请求,先去redis中找,找到了就直接返回,没找到就查数据库,如果数据查出来不为空,
    那么就将数据库数据缓存到redis,查出来数据为空,就返回空。当数据不存在时,redis里面肯定没有,数据库里也没有,每次请求都要去数据库里查,并且还查不到,查不到就不会缓存到redis,所以每一次都查数据库,高并发下数据库就容易崩坏。

缓存穿透的应对措施:

  1. 对请求增加校验机制
    对一些访问量比较大的请求,给他需要的参数字段设置固定的格式,比如查询课程信息,需要的参数为课程Id,给这个字段设定格式为课程Id+课程名的MD5,不满足这个格式的参数直接就进不来,都进不到查询缓存那一步,更别说查询数据库了。
  2. 使用布隆过滤器
    布隆过滤器加在缓存与数据库之间,他的作用是判断一个数据在某个集合中是否存在,存在返回1,不存在返回0,他如果判断为不存在,那就是一定不存在,但是他如果判断为存在,这就不一定存在,可能还是不存在。我们只需要利用它判断不存在的正确率为100就行,让他挡在数据库前面,判断不存在就直接返回,判断存在,实际上不存在,这种情况是小概率事件,因此请求就不会大量打到数据库上。

上述两种措施通常搭配缓存预热来使用,在高并发场景下,系统上线前,把数据库中的数据尽可能都缓存一遍,避免临时写入缓存。

  1. 修改代码逻辑,缓存空值
    通过参数校验以后,缓存中不存在,去查数据库,数据库也不存在,那么我们也要缓存这个不存在的值,使得最起码当前这个请求下次再来的时候,不会打到数据库上。

缓存击穿

描述:缓存击穿描述的是热点数据在某一个时刻,它在redis中设置的缓存过期了,但是外界还是会有大量的请求访问这个数据,缓存中没有,那这些请求就全部打到数据库上了,瞬间耗光数据库资源,导致数据库不可用。

缓存击穿解决措施:

  1. 加锁互斥
    在并发的多个请求中,只有第一个请求线程能拿到锁并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程将数据写入缓存后,直接走缓存。

  2. 热点数据不过期。
    直接将缓存设置为不过期,然后由定时任务去异步加载数据,更新缓存。

热点数据不过期适用于比较极端的场景,例如流量特别特别大的场景,使用时需要考虑业务能接受数据不一致的时间,还有就是异常情况的处理,不要到时候缓存刷新不上,一直是脏数据,那就凉了。

缓存雪崩

描述:redis中大量的Key在同一时间过期,大量的请求直接打在数据库上,瞬间耗光数据库资源,导致数据库不可用。

缓存雪崩应对措施:

  1. 使用同步锁控制查询数据库的线程
    加锁排队,每次只能有一个线程查询数据库写入缓存,效率很低,但可以防止数据库被冲垮。

  2. 为同一类型的key设置不同的过期时间
    比如,给同一类服务的缓存数据的过期时间设置为300秒再加一个随机数,使得这一类缓存的过期分布均匀。

  3. 采用定时更新缓存的策略
    写一个定时任务,一批缓存快过期或者过期的时候,更新它们的过期时间。

  4. 双层缓存策略
    对数据缓存两次,K1为初始缓存,过期时间短;K2为拷贝缓存,过期时间长,当K1过期了可以访问K2。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
缓存穿透缓存击穿缓存雪崩是常见的缓存相关问题,它们可能导致缓存失效或性能下降。下面是对它们的原因和解决方法的简要说明: 1. 缓存穿透缓存穿透是指请求的数据在缓存和数据库中都不存在,导致每次请求都要访问数据库,增加了数据库负载。主要原因是恶意攻击或错误的查询。 解决方法: - 使用布隆过滤器:在查询前使用布隆过滤器检查请求是否有效,如果无效则直接返回,避免对数据库的查询。 - 设置空对象缓存:将数据库中不存在的值也缓存起来,可以防止频繁查询。 2. 缓存击穿缓存击穿是指一个热点数据失效,导致大量请求同时访问数据库,造成数据库压力过大。主要原因是热点数据过期或删除。 解决方法: - 设置热点数据永不过期:针对热点数据设置永不过期,确保即使失效也能从缓存中获取,并在后台异步更新缓存。 - 互斥锁(Mutex):当缓存失效时,只允许一个线程访问数据库并更新缓存,其他线程等待获取缓存数据。 3. 缓存雪崩缓存雪崩是指缓存中大量的数据同时失效,导致所有请求都要访问数据库,造成数据库负载过大。主要原因是缓存中的数据同时过期。 解决方法: - 设置随机过期时间:为缓存数据设置随机的过期时间,避免大量数据同时失效。 - 使用分布式缓存:将缓存分布在不同的节点上,提高系统的可用性和容错能力。 - 数据预热:提前加载热点数据到缓存中,避免在高并发时突然访问数据库。 以上是对缓存穿透缓存击穿缓存雪崩问题的原因和解决方法的简要介绍,实际应用中可能还需要结合具体场景进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值