缓存穿透、雪崩、击穿

前言


我们平常的项目中多多少少都会使用到缓存,因为一些数据我们没有必要每次查询都查询数据库,对于高并发的项目,每次都查询数据库,对数据库是灾难性的!!!

当我们查询一条数据的时候,先去查询缓存,如果有缓存就直接返回,如果没有才会去查数据库,然后返回。
在这里插入图片描述

缓存穿透


什么是缓存穿透

正常情况下,我们去查询数据都是存在。
那么请求去查询一条压根儿数据库中根本就不存在的数据,也就是缓存和数据库都查询不到这条数据,但是请求每次都会打到数据库上面去。
这种查询不存在数据的现象我们称为缓存穿透。

会带来的问题

如果有黑客会对你的系统进行攻击,拿一个不存在的id 去查询数据,会产生大量的请求到数据库去查询。可能会导致你的数据库由于压力过大而宕掉。

怎么解决

  1. 缓存空值
    之所以会发生穿透,就是因为缓存中没有存储这些空数据的key。从而导致每次查询都 到数据库去了。那么我们就可以为这些key对应的值设置为null 丢到缓存里面去。后面再出现查询这个key 的请求的时候,直接返回null 。这样,就不用在到数据库中去走一圈了
  2. BloomFilter(布隆过滤器)
    布隆过滤器可以用于检索一个元素是否在一个集合中。
    优点是空间效率和查询时间都远远超过一般的算法,
    缺点是有一定的误识别率和删除困难。
    在这里插入图片描述
    原理:
    布隆过滤器的原理是,当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。这就是布隆过滤器的基本思想。
    图片源地址
    在这里插入图片描述

简而言之,言而简之就是我们先把我们数据库的数据都加载到我们的过滤器中,比如数据库的id现在有:1、2、3

那就用id:1 为例子他在上图中经过三次hash之后,把三次原本值0的地方改为1

下次数据进来查询的时候如果id的值是1,那么我就把1拿去三次hash 发现三次hash的值,跟上面的三个位置完全一样,那就能证明过滤器中有1的
反之如果不一样就说明不存在了

怎么选择方案

  • 针对于一些恶意攻击,攻击带过来的大量key 是不存在的 ——> 方案二
  • 对于空数据的key有限的,重复率比较高的 ——> 方案一

缓存击穿


什么是缓存击穿

在高并发的系统中,大量的请求同时查询一个key时,此时key正好失效,就会导致大量的请求直接打到DB上,这种现象称作缓存击穿

带来的问题

造成某一时间点数据库请求量过大,压力剧增,可能导致数据库服务宕机

如何解决

多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个 互斥锁来锁住它。其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。(俗称的双重检测)

缓存雪崩


什么是缓存雪崩

某一时刻缓存大规模的失效(缓存服务宕机、大量缓存失效…)会有大量的请求进来直接打到DB上。
带来的问题
大量请求打到DB上,导致DB宕机

如何解决

事前:

  • 热点数据过期时间设置为不过期
  • 使用集群缓存,保证缓存服务的高可用

这种方案就是在发生雪崩前对缓存集群实现高可用,如果是使用 Redis,可以使用 主从+哨兵 ,Redis Cluster 来避免 Redis 全盘崩溃的情况。

事中:

  • 本地缓存、限流降级,避免DB被打挂
  • 使用 ehcache 本地缓存的目的也是考虑在 Redis Cluster 完全不可用的时候,ehcache 本地缓存还能够支撑一阵。
  • 使用 Hystrix进行限流 & 降级 ,比如一秒来了5000个请求,我们可以设置假设只能有一 秒 2000个请求能通过这个组件,那么其他剩余的 3000 请求就会走限流逻辑。然后去调用我们自己开发的降级组件(降级),比如设置的一些默认值呀之类的。以此来保护最后的 MySQL 不会被大量的请求给打死。

事后:

  • 开启Redis持久化机制,尽快恢复缓存集群
    一旦重启,就能从磁盘上自动加载数据恢复内存中的数据。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值