缓存穿透,缓存雪崩,缓存击穿,缓存一致性解决方案分析

首先我们通过明确其中的概念,再来分析解决方案,这里的缓存我们以redis为例,当然其他的缓存技术,出现的问题以及解决思路大致是一样的

缓存穿透:是指查询一个一定不存在的数据,通常我们都会先查缓存,缓存中没有查数据库,数据库也没有则不写入缓存,那么这个不存在的数据每次请求数据库,失去了缓存的意义。特别是流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,会带来一系列问题。

解决方案:
1.空值存储法:查不到这个数据的时,我们也把他放进缓存,以redis为例,不存在的key相对的value可以设置为null
并且加上一定到过期时间,来保证,下一次的缓存命中.
2.布隆过滤器:就是把把所有能查到的key存在一个缓存中,我们先去查询这个缓存,判断key是否存在,
不存在则不去触发我们的需要查询的业务缓存,当然了这里也可以放入系统内存中,具体看内存大小和业务场景.

缓存雪崩:缓存在某一时刻大量失效,请求全部转发到DB瞬时压力过重导致崩溃

解决方案:
1.1分类错峰:对于不同业务热点数据进行分级设置缓存失效时间基础上增加一个随机值,比如1-5分钟,这样每个缓存过期时间的重复率就会降低,就很难引发集
1.2分类错峰+随机值=过期时间:同一类业务数据稀释的更加离散
2.采用加锁计数,或者使用合理的队列数量来减少数据库压力,缺点是降低了系统的吞吐量(不建议)
3.如果是因为某台缓存服务器宕机,可以考虑做主从
4.采用二级缓存,但是要考虑一致性问题

缓存击穿:在高并发下,对特定的值进行查询,但是这个时候缓存过期了,缓存没有命中,导致大量请求直接落到DB,这个和缓存雪崩的区别在于这里针对某一key缓存失效,前者则是很多key都失效。

解决方案:
1.对缓存查询加锁,如果KEY不存在,就加锁,然后查DB入缓存,然后解锁,其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入DB查询
2.永久性加锁,大多数情况下几款爆款热点书库很难对DB造成压垮性的压力。所以让缓存永不过期。对于常规公司来说也是可以接受的
3.增加二级缓存,保证redis没有二级缓存兜底即可

缓存一致性:不管是先写MySQL数据库,再删除Redis缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况。举一个例子:

  • 1.如果删除了缓存Redis,还没有来得及写库MySQL,另一个线程就来读取,发现缓存为空,则去数据库中读取数据写入缓存,此时缓存中为脏数据。

  • 2.如果先写了库,在删除缓存前,写库的线程宕机了,没有删除掉缓存,则也会出现数据不一致情况。

    因为写和读是并发的,没法保证顺序,就会出现缓存和数据库的数据不一致的问题。
    如来解决?这里给出两个解决方案,先易后难,结合业务和技术选择使用

     解决方案:
     1. 对删除缓存进行重试,数据的一致性要求越高,我越是重试得快。
     2. 定期全量更新,简单地说,就是我定期把缓存全部清掉,然后再全量加载。
     3. 采用双删机制,删除缓存,写入db,等待一段时间再去删除.
     4. 给所有的缓存一个失效期(任何不一致,都可以靠失效期解决,失效期越短,
     .数据一致性越高。但查数据库就会越频繁。因此失效期应该根据业务来定。)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值