0%

缓存穿透、缓存击穿和缓存雪崩问题

在分布式架构中,缓存是平衡性能与数据库压力的关键组件.然而,简单地引入 Redis 并不等于高枕无忧,错误的缓存策略反而会成为系统中最致命的单点.

缓存穿透、缓存击穿与缓存雪崩正是三种典型且破坏性极强的缓存失效场景,它们极易在高并发下导致数据库被打穿、服务雪崩式宕机.

本文将从技术原理层面深入剖析这三种问题的本质区别,并提供从代码到架构的多层级解决方案,包括但不限于:

  • 布隆过滤器(Bloom Filter)应对穿透
  • 互斥锁(Mutex Lock)与逻辑过期化解击穿
  • 密钥过期时间分散化与熔断降级策略预防雪崩
    帮助你构建一个兼具高性能和高可用的健壮缓存系统.

1. 缓存穿透

1.1. 问题描述

访问缓存中没有的数据,会去访问数据库获取.此时恶意访问者可以通过查询不存在的数据,来不断的访问数据库,导致数据库压力过大,甚至宕机.这种行为就好像穿透了缓存层直达数据库,所以叫缓存穿透.

1.2. 解决措施

1.2.1. 布隆过滤器

布隆过滤器是一种空间效率高的概率型数据结构,用于判断一个元素是否存在于一个集合中.它的基本原理是将一个元素通过多个哈希函数映射到一个位数组上的多个位置,将这些位置的值设为1.当查询一个元素是否存在时,只需要判断这些位置的值是否都为1即可.如果有一个位置的值为0,则可以确定该元素不存在于集合中;如果所有位置的值都为1,则只能确定该元素可能存在于集合中.
布隆过滤器原理

布隆过滤器的优势在于它的空间效率高,只需要一个位数组和多个哈希函数即可实现.同时,它的查询时间复杂度为O(k),其中k为哈希函数的数量.

在缓存穿透问题中,我们可以使用布隆过滤器来缓存所有可能存在的key.当收到一个查询请求时,先使用布隆过滤器判断该key是否存在于缓存中.如果不存在,则直接返回空结果,避免继续访问数据库.如果存在,则继续访问缓存或数据库,根据实际情况返回结果.

2. 缓存击穿

2.1. 问题描述

缓存击穿是指某个热点数据在缓存中过期失效,造成大量并发请求同时到达数据库,导致数据库压力过大,甚至宕机.

2.2. 解决措施

2.2.1. 互斥锁

互斥锁是一种用于保护共享资源的同步机制,确保同一时间只有一个线程能够访问共享资源.
当一个线程访问共享资源时,如果发现缓存中没有该数据,则会先尝试获取互斥锁.如果获取成功,则会去数据库查询数据,并将数据放入缓存中.如果获取失败,则会等待锁的释放,然后再次尝试获取互斥锁.

  • Zookeeper 基于临时序号结点+监听机制
  • Redisson 基于Redlock算法的分布式锁,性能不如ZK,但在使用Redis的项目起码不用动整体架构

2.2.2. 热点数据永不过期

设置定时任务,定期更新热点数据的缓存.

2.2.3. 接口限流或降级

对热点数据的访问进行限流,防止大量并发请求同时到达数据库.当请求量超过一定阈值时,可以选择降级处理,直接返回缓存中的旧数据或默认数据.

3. 缓存雪崩

3.1. 问题描述

缓存雪崩是指在缓存中大量数据同时过期失效,导致大量并发请求同时到达数据库,导致数据库压力过大,甚至宕机.

3.2. 解决措施

3.2.1. 缓存过期时间分散化

为了避免缓存雪崩,可以将缓存数据的过期时间设置为随机值,而不是固定值.这样可以确保缓存数据在不同时间过期,避免同时过期失效.

3.2.2. 热点数据永不过期

设置定时任务,定期更新热点数据的缓存.

3.2.3. 分布式锁

使用分布式锁来保护缓存数据的更新操作,确保同一时间只有一个线程能够更新缓存数据.这样可以避免大量并发请求同时到达数据库.

欢迎关注我的其它发布渠道

-------------我到底啦 感谢大佬-------------