Skip to main content

Redis缓存雪崩和穿透

· 4 min read
Zeffon Wu

在使用 redis 作为缓存层时,有时候不好的程序设计会导致 Redis 缓存雪崩和穿透问题。

前言

正文

缓存雪崩

**雪崩** :Redis 中有大量的 key,会设置过期时间。如果过期时间有太多重合的,那么在某个时间点会有大量key失效了或是由于Redis宕机了 恰好这时候有很大很大的流量流入进来。那么这个时候所有的请求不会再经过Redis缓存层,而是都会直接打在数据库上,数据库可能会处理不过来导致宕机崩溃

原本是会经过缓冲层 20-aualanche-01.png 由于缓存失效或者宕机 20-aualanche-02.png 请求直接访问 Mysql 20-aualanche-03.png

**预防方案**

  1. 采用 Key 永不过期机制
  2. 采用 key 过期时间错开(推荐)
  3. 多缓存结合使用

缓存穿透

**穿透** : 接受一个 id,先从 redis 查询有没有对应值,没有再从数据中查询,查询结果进行判断,有数据才将其写进 redis 里。下次再查询就不要查询数据库了,而 redis 起了一个缓存的作用。但是这种情况只适合id是存在数据库。如果用户传入一个非法、数据库不存在的 id,那么一直使用该 id 请求的话,程序就会一直访问数据库,这样无法缓存了,直接把缓存穿透了。

**处理方案** :不管数据库查询的结果有没有数据,都将其进行缓存。把空的数据(空字符串、空对象、空数组、空列表)缓存起来。(就是针对一个不存在的 key 去为它设置一个空值,即使后面我们可能会使用这个不存在的 key 时,set 时也会把之前的空值覆盖的)

**布隆过滤器** : 可以迅速地判断一个元素是否在一个集合里,相当一种拦截器,是在 redis 前面进行拦截。以 HashMap 的 Key-Value 的形式可以在 O(1) 的时间复杂度内返回结果,效率奇高。但是存储容量占比高,数据量太多时会占据内存并且有 1%误判率的缺点。

区别

缓存穿透单个key的大量请求打在数据库上,缓存雪崩大量key失效导致大量请求直接打在数据库