缓存雪崩、缓存击穿、缓存穿透

1. 缓存雪崩

在使用redis或者memcache等缓存时,大量key在同一时间集体过期失效,这时大量的访问将会请求到db,可能导致系统崩溃。

解决方案

  • 热点数据不过期:这样访问大量热点数据就不存在缓存集体失效导致雪崩问题。
  • 使用互斥锁:只让一个线程构建缓存,其他线程等待构建缓存的线程执行完,重新从缓存获取数据才可以,每个时刻只有一个线程在执行请求,减轻了db的压力,但缺点也很明显,降低了系统的qps。
  • key设置随机失效时间:随机的失效时间即可从一定长度上避免这种问题,在缓存进行失效时间设置的时候,从某个适当的值域中随机一个时间作为失效时间即可。

2. 缓存击穿

缓存击穿是缓存雪崩的一个特例,系统中对热点数据缓存也存在失效时间,在热点的缓存到达失效时间时,此时可能依然会有大量的请求到达系统,没有了缓存层的保护,这些请求同样的会到达db从而可能引起崩溃。缓存击穿与缓存雪崩的区别在于缓存击穿是对于特定的热点数据来说,而雪崩对于是全部数据来说。

解决方案

  • 热点数据不过期
  • 二级缓存:对于热点数据进行二级缓存,并对于不同级别的缓存设定不同的失效时间,则请求不会直接击穿缓存层到达数据库。
  • LRU算法:根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。存在缓存污染——偶发性的、周期性的批量操作会导致LRU命中率急剧下降,这时候缓存中的数据大部分都不是热点数据。
  • LRU-K算法 :主要目的是为了解决LRU算法“缓存污染”的问题,其核心思想是将“最近使用过1次”的判断标准扩展为“最近使用过K次”。也就是说没有到达K次访问的数据并不会被缓存,这也意味着需要对于缓存数据的访问次数进行计数,并且访问记录不能无限记录,也需要使用替换算法进行替换。当需要淘汰数据时,LRU-K会淘汰第K次访问时间距当前时间最大的数据。K值增大,命中率会更高,但是适应性差(清除一个缓存需要大量的数据访问,一般选择LRU-2)

3. 缓存穿透

查询不存在的数据,如果缓存中无该数据的信息,则会去数据库进行查询,而数据库中也不存在该数据,这种查询一定不存在的数据对系统来说可能是一种危险,如果有人恶意用这种一定不存在的数据来频繁请求系统,就是攻击系统,大量恶意请求都会请求到db从而导致系统瘫痪。

解决方案

  • 布隆过滤器:将所有可能的查询条件生成一个bitmap,在进行数据库查询之前会使用这个bitmap进行过滤,如果不在其中则直接过滤,从而减轻数据库层面的压力。
  • 接口层增加校验:如用户鉴权校验,id做基础校验,id<=0的直接拦截
  • 设置空值缓存:缓存查询发现不存在该数据,将该key与null值写入缓存中,设置较短的过期时间,比如3分钟,这样则可以应对短时间的大量的该key攻击,设置为较短的失效时间是因为该值可能业务无关,存在意义不大,且该次的查询也未必是攻击者发起,无过久存储的必要,故可以早点失效。

参考

https://www.toutiao.com/a6621760903832404488/

https://zhuanlan.zhihu.com/p/78212068

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值