2020-07-02 20:34:22
Redis 缓存穿透、缓存击穿、缓存雪崩是 Redis 与持久化数据库配合使用时常见的高可用问题,以下是具体解释及解决方案:
什么是缓存穿透缓存穿透指用户查询的数据在 Redis 中未命中,且在持久化数据库(如 MySQL)中也不存在,导致大量请求直接穿透缓存层,直接访问数据库,给数据库带来巨大压力。

使用布隆过滤器:
布隆过滤器是一种数据结构,通过哈希算法将所有可能查询的参数存储在过滤器中。
在控制层先对查询参数进行校验,若参数不在布隆过滤器中,则直接丢弃请求,避免对底层存储系统的压力。
布隆过滤器部署在 Redis 前面,拦截无效请求,减少对 Redis 和持久化层的冲击。

当持久化数据库中未查询到数据时,返回一个空对象,并将该空对象缓存到 Redis 中,同时设置过期时间。
后续请求直接访问缓存中的空对象,避免对数据库的冲击。

大量空对象占用内存空间,增加内存压力。
空对象过期后,请求压力仍会打到数据库,可能影响数据一致性。
缓存击穿指某个热点数据的 key 在过期的瞬间,大量请求同时访问该 key,由于缓存未命中,所有请求直接访问数据库,导致数据库瞬间压力过大。

与缓存穿透的区别:
缓存击穿是针对热点数据的 key 过期,大量请求访问同一 key。
缓存穿透是访问的数据不存在,大量请求访问不同但均不存在的 key。
解决方案:
热点数据永不过期:
不设置热点数据的过期时间,避免因过期导致击穿。
分布式锁:
在访问 Redis 前先获取分布式锁,保证同一时间只有一个服务访问该 key。
其他服务等待获取锁,避免同时访问数据库。
锁的压力较大,需合理设计锁的粒度和超时时间。
缓存雪崩指在某一时间段内,大量缓存 key 集中过期,或 Redis 宕机,导致大量请求直接访问数据库,造成数据库压力过大甚至宕机。

常见场景:
热点活动中,大量商品 key 设置在同一时间过期。
Redis 宕机,导致所有缓存失效。
解决方案:
Redis 高可用:
搭建 Redis 集群,采用主备或异地多活部署,避免单点故障。
限流降级:
在缓存失效时,通过锁限制访问顺序,或关闭非核心服务,保障核心服务运行。
数据预热:
在正式上线前,预先访问需要的数据,将数据写入缓存。
设置不同的过期时间,避免大量 key 集中过期,均衡缓存失效时间。
通过合理设计缓存策略和解决方案,可以有效避免缓存穿透、缓存击穿和缓存雪崩问题,提高系统的可用性和性能。