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

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

在实际应用中Redis常常与MYSQL等传统数据库一起使用,Redis看作是MYSQL的缓存,当收到一个查询命令时,首先到Redis中查找,若Redis中不存在该条记录再访问MYSQL进行查询,查询到结果后再将结果放入缓存中

缓存穿透

缓存穿透指的是在查询一个一定不存在的数据时,由于缓存是不命中的,所以需要从数据库中查询,查不到数据则不写入缓存,这将导致不存在的数据每次请求都要到数据库中查询,如果大量请求同时请求一个不存在的产品,这些请求就会全部被送到持久层数据库,给数据库造成一定的压力,甚至导致数据库宕机

解决方案一:缓存空对象

若持久层数据库查询不到结果则返回空对象,并将空对象也写入缓存中,同时设置一个过期时间,之后再访问这个数据将会从缓存中读到空对象
在这里插入图片描述
但这种方法缺陷较大,黑客在对服务器进行缓存穿透攻击时可能会提交大量不存在的且不相同的数据请求,这样每一次的请求依然能穿透缓存到达数据库,并且由于Redis缓存淘汰策略的原因,这些存入Redis的空值很可能会把其他有用的值挤出内存。

解决方案二:布隆过滤器

布隆过滤器是一种数据结构,是一个二进制的数组或者说是一个二进制向量,用于检测集合中是否存在特定的元素,具有很好的空间和时间效率。

如下是一个长为16的布隆过滤器,初始值为0。

在这里插入图片描述

当我们需要添加数据时,我们可以利用多个哈希函数,例如这里我们给定三个哈希函数hash1,hash2和hash3,当向过滤器中添加数据时,添加的数据通过哈希函数映射到三个下标x1,x2,x3,我们假设这里得到的是3、6、8,那么该数据也就映射到了过滤器的3、6、8三个位置,我们将这三个位置的值置为1,我们重复添加三个数据,得到下图:

在这里插入图片描述

当我们需要去检测集合中是否存在一个数据时,我们使用同样的方法去得到该数据的3个hash码,通过这三个hash码我们到过滤器中查看相应的值,若三个哈希码在过滤器中对应的值存在0,则集合中不存在该数据。例如下方的data4,通过三个哈希函数得到了3、7、14,其中14对应的值为0,因此集合中不存在data4。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1JOIlk1Y-1592036162976)(C:\Users\13719\AppData\Roaming\Typora\typora-user-images\image-20200612202458417.png)]

既然涉及到了哈希函数,那么显然存在着哈希冲突问题,即存在着这样一种可能,一个集合中不存在的数据通过哈希函数得到的哈希码与其他数据的哈希码相同,那么其映射到布隆过滤器中的值也都为1,会被判定为存在。因此布隆过滤器判断存在的数据不一定存在,但判断不存在的数据一定不存在。

另外还有一点值得注意的是,布隆过滤器有多个哈希函数,虽然得到哈希码后在过滤器中查找的过程效率很高,但计算哈希码的需要消耗一定的时间,因此哈希函数越多,查找的效率也就越低,但误判率也就越高,反之查找效率低但误判率高。此外不论过滤器的长度也与误判率相关

布隆过滤器的删除比较麻烦,若我们想从过滤器中删除一个数据,由于哈希冲突的原因,该数据的哈希码可能和其他数据部分重复,此时要删除该数据就不能直接删除。我们可以通过为每一位增加一个计数器来辅助数据的删除。但是使用布隆过滤器的目的之一是高效,增加计数器会降低布隆过滤器的使用效率,在实际应用中一般不去删除布隆过滤器的数据。

缓存雪崩

缓存雪崩是指当缓存集中失效或缓存服务器重启时,大量的请求全部冲击到持久层数据库,给数据库带来大量的压力。

解决方案一:缓存预热

在服务正式上线之前,先把可能的数据预先访问一遍,使得可能大量访问的数据被加载到缓存中,在即将发生大量并发前手动触发加载缓存不同的key,设置不同的过期时间,使得缓存失效时间尽可能的均匀,避免集中失效。

解决方案二:限流——加锁或排队

在缓存失效后,通过加锁或者队列的方式来控制数读数据库写缓存的线程的数量。例如对于某个key进行上锁,使得同一时间只允许一个线程对该数据进行读或写

缓存击穿

缓存击穿指某个热点key可能在某些时间点被超高并发的访问,当热点key失效时,这些请求会全部送到持久层数据库,给数据库带来压力。

解决方案一:互斥锁

当一格请求想要请求某个key时,若该key在缓存中未命中,则对该key上锁,再从数据库中加载数据,加载完成后释放锁,若在这过程中,其他线程希望获取该数据,则睡眠一定时间后重试

解决方案二:不设置过期时间

不设置过期时间,而是将过期时间存放在key对应的value中,读取key时若发现存在时间超过过期时间则更新缓存

解决方案三:设置两个过期时间

在对应的value中一格比过期时间t0短一些的过期时间t1,当t1过期时,延长t1并更新缓存

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值