缓存穿透、缓存并发和缓存雪崩问题

看了一篇特别有意思的文章,简单记录一下这3个问题。
首先,缓存穿透、缓存并发、缓存雪崩是常见的由于并发量大而导致的缓存问题,下面简单介绍产生原因和解决方法。

一:缓存穿透:

缓存穿透一般是由于无意造成或者遭受了恶意攻击。
缓存穿透:查询一个不存在的key,进行大量的高并发查询,而缓存不命中时就会调用数据库查询,由于查询不到结果也不会写入缓存,这样每次请求都要穿透到后端数据库系统进行查询,造成缓存穿透。当并发量到达一定程度,可能我们的DB就down了。

解决措施:

1:为这种情况设置一个空结果,记录在缓存中。
比如说,找不到结果时,返回的结果为空(造成这个的一种是缓存穿透,还有一种是正常的找不到结果),这种情况就简单粗暴的,把这个空的结果写进缓存,这样之后的相同的查询请求就会都命中缓存了,减少了DB压力,不过这个时间不宜过长,基本5min即可。

2:对入参进行过滤。
当收到恶意攻击时,攻击者一般会变换不同的参数进行查询,这时第一种情况就没办法了,不仅没办法,也会存入很多无效的数据。那么这个时候,就是对请求的入参进行过滤。
比如使用ID进行查询,可以对ID的格式进行分析,不符合格式规则,直接拒绝,不会进行后面的请求。

这里引入一个布隆过滤器的概念,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层数据库的查询压力。

3:其他锦上添花的操作
数据库读写分离,接口限流操作。

4:互斥锁排队
百度了一下还有这个……奉上参考文档(希望有一天能看懂)
https://blog.csdn.net/fanrenxiang/article/details/80542580

缓存并发

缓存并发产生的原因,一般是分布式结构设计不合理。
比如在高并发场景下,一个缓存如果失效,可能出现多个进程同时查询DB,同时设置缓存的情况,如果并发确实很大,这也可能造成DB压力过大,还有缓存频繁更新的问题。

解决措施

1:分布式锁
保证每一个key同时只有一个线程去查询,其他线程都得等待。不过这个对分布式锁要求很高。

2:本地锁
也是加锁,通过本地锁方式线程只有一个线程去数据库查询数据,其他线程只需等待。
但是,这个只能限制一个服务节点只有一个线程去查询,如果服务多个节点,还是会存在问题。

3:软过期
对缓存中的数据设置失效时间。
虽然缓存自身有过期时间,而我们这个业务层在数据中存储过期时间信息,通过程序判断是否过期并更新,在即将过期的时候,将缓存失效延长,然后用一个线程去获取新的数据,而其他的线程,由于延长了失效时间,还能正常调用。

缓存雪崩

大量缓存在同一时间段内失效,或者是重启了缓存服务器,导致大量请求落在DB上,造成负载飙高,最终压死了。

解决措施

1:不同类别的缓存设置不同的失效时间,或者相同的数据不同的请求设置不同的时间,比如说,可以定义一个基础时间,然后在给个1~2s内的随机数叠加,这样错峰操作;
2:上文一样,加锁排队。
3:设置缓存备份。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值