Redis缓存穿透,缓存雪崩,缓存击穿

缓存穿透

概念

缓存穿透是指不断的请求缓存中不存在的数据, 则所有请求全部落在了数据库层, 高并发的情况下, 就直接影响了整个系统的业务, 甚至可能导致系统崩溃

过程

  1. 根据key从缓存中获取数据;
  2. 如果数据不为空,直接返回;
  3. 如果数据为空,进行数据库查询;
  4. 如果从数据库查询出的数据不为空,则放入缓存(设定过期时间)

不断的重复第三步, 比如要查一个商品的信息, 传入 -1, 所有请求就直接落在了数据库上

解决

  1. 设置空对象缓存
    数据库取出来的数据如果是空值, 同样也缓存, 但是设置一个比较短的缓存时间, 这样可以一定意义上减缓缓存穿透
  2. 布隆过滤器
    布隆过滤器本质上一种空间效率极高的概率型算法和数据结构,主要用来判断一个元素是否在集合中存在。

// 使用

可以提前将真实正确的key,在添加完成之后便加入到过滤器当中,每次再进行查询时,先确认要查询的key是否在过滤器当中,如果不在,

则说明key为非法key,则不需要进行后续的查询步骤了。

缓存雪崩

概念

缓存雪崩是指缓存中数据大批量同一时间过期或者redis服务挂了,而查询数据量巨大,引起数据库压力过大。

过程

  1. 商城中缓存了商品的信息,时间为24小时
  2. 在第二天的0点, 正好有一个抢购活动
  3. 抢购开始的时候, 全部缓存失效, 同一时间全部的商品信息查询落到数据库上, 导致可能压力过大

解决

  1. 可以在做数据缓存的时候, 按分类进行缓存, 添加不同的缓存时间
  2. 缓存的同时, 对缓存时间加上一个随机数, 以至于不会让所有缓存同一时间大量失效
  3. 对于redis服务挂掉的问题,可以实现redis的高可用主从架构, 并且做redis的持久化, 在redis挂掉的同时时读取本地缓存数据, 同时恢复redis服务加载持久化的数据

缓存击穿

概念

缓存击穿和缓存雪崩有点像, 不过不是大面积的缓存失效

缓存击穿指的是缓存中某一个key的值不断的接收着大量的请求, 而在这个key值失效的瞬间, 大量的请求落在了数据库上, 从而导致数据库可能压力过大

过程

  1. 有key1,key2…等键值对应的缓存
  2. key1属于热度商品, 不断的扛着请求
  3. key1过期时间到了, 请求瞬间落在了数据库上, 导致可能压力过大

解决

  1. 加分布式锁或者分布式队列
    用加分布式锁或者分布式队列的方式保证缓存的单线程写,从而避免失效时大量的并发请求落到底层存储系统上。在加锁方法内先从缓存中再获取一次(防止另外的线程优先获取锁已经写入了缓存),没有再查DB写入缓存。 (当然也可以: 在没有获取锁的线程中一直轮询缓存,至超时)
  2. 添加超时标记
    在缓存的对象上增加一个属性来标识超时时间,当获取到数据后,校验数据内部的标记时间,判定是否快超时了,如果是,异步发起一个线程(控制好并发)去主动更新该缓存。
  3. 另外还有一个粗暴的方法,如果你的热点数据要求实时性比较低,那么可以设置热点数据在热点时段不过期,在访问低峰期过期,比如每天凌晨过期。


Redis

本文链接:

https://coolhu.com/Redis_bug.html

你必须登录后才能发表评论

0 评论