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

一、缓存雪崩

大量缓存数据在同一时间过期或者Redis故障宕机时,如果此时有大量的用户请求,都无法在Redis中处理,全部请求都直接访问数据库,从而导致数据库压力骤增,严重的会造成整个系统崩溃,这就是缓存雪崩问题。

处理方案:

  • 大量数据同一时间过期限流降级处理均匀设置过期时间,防止同一时间大量数据过期情况。
  • Redis故障宕机主从复制+Redis持久化策略

缓存雪崩、缓存击穿、缓存穿透_第1张图片

缓存雪崩、缓存击穿、缓存穿透_第2张图片

 二、缓存击穿

在平常的高并发系统中,大量的请求同时查询一个key时,此时这个key刚好失效,导致大量的请求都打到数据库上,造成数据库极大的压力,这就是缓存击穿问题。

缓存雪崩、缓存击穿、缓存穿透_第3张图片

处理方案:

互斥锁方案,保证同一时间只有一个业务线程去数据库获取数据填充到Redis中,更新缓存,未能获取互斥锁的请求,需要等待锁释放后重新读取缓存。获取成功直接返回结果获取失败则再次尝试获取锁,重复上述流程

缓存雪崩、缓存击穿、缓存穿透_第4张图片

redis分布式锁传送入口------------>

三、缓存穿透

用户在不断访问一个在缓存和数据库中都没有的数据,缓存无法命中,从而导致一直请求数据库,流量过大就会导致数据库的崩溃,这就是缓存穿透问题。

缓存雪崩、缓存击穿、缓存穿透_第5张图片

处理方案:

  • 接口层增加校验,如用户鉴权等;
  • 使用布隆过滤器快速判断数据是否存在,避免通过查询数据库来判断数据是否存在
  • 将空结果(NULL)或默认查询结果存入到缓存中,并设置值过期时间。

缓存雪崩、缓存击穿、缓存穿透_第6张图片

四、布隆过滤器

布隆过滤器由「初始值都为 0 的位图数组」「 N 个哈希函数」两部分组成。当我们在写入数据库数据时,在布隆过滤器里做个标记,这样下次查询数据是否在数据库时,只需要查询布隆过滤器,如果查询到数据没有被标记,说明不在数据库中。

布隆过滤器会通过 3 个操作完成标记:

  • 第一步,使用 N 个哈希函数分别对数据做哈希计算,得到 N 个哈希值;
  • 第二步,将第一步得到的 N 个哈希值对位图数组的长度取模,得到每个哈希值在位图数组的对应位置。
  • 第三步,将每个哈希值在位图数组的对应位置的值设置为 1;

举个例子,假设有一个位图数组长度为 8,哈希函数 3 个的布隆过滤器。

图片

在数据库写入数据 x 后,把数据 x 标记在布隆过滤器时,数据 x 会被 3 个哈希函数分别计算出 3 个哈希值,然后在对这 3 个哈希值对 8 取模,假设取模的结果为 1、4、6,然后把位图数组的第 1、4、6 位置的值设置为 1。当应用要查询数据 x 是否数据库时,通过布隆过滤器只要查到位图数组的第 1、4、6 位置的值是否全为 1,只要有一个为 0,就认为数据 x 不在数据库中

布隆过滤器由于是基于哈希函数实现查找的,高效查找的同时存在哈希冲突的可能性,比如数据 x 和数据 y 可能都落在第 1、4、6 位置,而事实上,可能数据库中并不存在数据 y,存在误判的情况。

所以,查询布隆过滤器说数据存在,并不一定证明数据库中存在这个数据,但是查询到数据不存在,数据库中一定就不存在这个数据

参考:
聊一聊缓存和数据库不一致性问题的产生及主流解决方案以及扩展的思考 - 掘金
什么是缓存雪崩、击穿、穿透? | 小林coding

你可能感兴趣的:(数据库/缓存,缓存,redis)