Redis缓存怎么高效用?怎么快速实现高性能数据缓存,解决缓存穿透和雪崩问题?

文章导读
Redis 高效使用核心在于合理设置过期时间、采用互斥锁或逻辑过期策略防止缓存击穿,利用布隆过滤器或缓存空值解决缓存穿透,并通过随机过期时间或二级缓存避免缓存雪崩。实现高性能缓存需结合业务场景,热点数据永不过期或定时更新,数据库查询加锁保护,同时监控 Redis 状态确保高可用。这些措施能显著降低数据库压力,提升系统响应速度,保障服务稳定性。
📋 目录
  1. redis 缓存穿透、缓存雪崩、热点 Key 问题分析及解决方案
  2. 再也不怕,缓存雪崩、击穿、穿透!
  3. 【黑马点评日记 03】实战:Redis 缓存穿透,缓存击穿,缓存雪崩全解析
  4. Redis 使用 | 缓存穿透,雪崩,击穿以及解决方案分析
  5. FAQ
A A

Redis 高效使用核心在于合理设置过期时间、采用互斥锁或逻辑过期策略防止缓存击穿,利用布隆过滤器或缓存空值解决缓存穿透,并通过随机过期时间或二级缓存避免缓存雪崩。实现高性能缓存需结合业务场景,热点数据永不过期或定时更新,数据库查询加锁保护,同时监控 Redis 状态确保高可用。这些措施能显著降低数据库压力,提升系统响应速度,保障服务稳定性。

redis 缓存穿透、缓存雪崩、热点 Key 问题分析及解决方案

我们通常使用 缓存 + 过期时间的策略来帮助我们加速接口的访问速度,减少了后端负载,同时保证功能的更新。缓存穿透 缓存系统,按照 KEY 去查询 VALUE,当 KEY 对应的 VALUE 一定不存在的时候并对 KEY 并发请求量很大的时候,就会对后端造成很大的压力。查询一个必然不存在的数据。比如文章表,查询一个不存在的 id,每次都会访问 DB,如果有人恶意破坏,很可能直接对 DB 造成影响。由于缓存不命中,每次都要查询持久层 (回源),从而失去缓存的意义。解决方法 缓存层缓存空值 缓存太多空值,占用更多空间。(优化:给个空值过期时间) 存储层更新代码了,缓存层还是空值。(优化:后台设置时主动删除空值,并缓存把值进去) 将数据库中所有的查询条件,放到 布隆过滤器中。当一个查询请求来临的时候,先经过布隆过滤器进行检查,如果请求存在这个条件中,那么继续执行,如果不在,直接丢弃。注意事项:使用布隆过滤器时,如果数据库中有 10000 个条件,那么布隆过滤器的容量 size 设置的要稍微比 10000 大一些,比如 12000。对于误判率的设置,根据实际项目,以及硬件设施来具体决定。但是一定不能设置为 0,并且误判率设置的越小,哈希函数跟数组长度都会更多跟更长,那么对硬件,内存中间的要求就会相应的高。private static BloomFilter bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.0001); 有了 size 跟误判率,那么布隆过滤器就会产生相应的哈希函数跟数组。综上:我们可以利用布隆过滤器,将 redis 缓存击穿控制在一个可容忍的范围内。缓存雪崩 (缓存失效) 如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩。缓存层宕掉后,流量会像奔逃的野牛一样,打向后端存储。解决办法 在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个 key 只允许一个线程查询数据和写缓存,其他线程等待;可以通过缓存 reload 机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存;不同的 key,设置不同的过期时间,让缓存失效的时间点尽量均匀;做二级缓存,或者双缓存策略:A1 为原始缓存,A2 为拷贝缓存;A1 失效时,可以访问 A2,A1 缓存失效时间设置为短期,A2 设置为长期。热点 key 这个 key 是一个热点 key(例如一个重要的新闻,一个热门的八卦新闻等等),所以这种 key 访问量可能非常大。(2026 年 4 月 11 日的资料)

再也不怕,缓存雪崩、击穿、穿透!

因为 Redis 是内存数据库,我们可以将数据库的数据缓存在 Redis 里,相当于数据缓存在内存,内存的读写速度比硬盘快好几个数量级,这样大大提高了系统性能。引入了缓存层,就会有缓存异常的三个问题,分别是缓存雪崩、缓存击穿、缓存穿透。这三个问题也是面试中很常考察的问题,我们不光要清楚地知道它们是怎么发生,还需要知道如何解决它们。话不多说,发车!缓存雪崩 通常我们为了保证缓存中的数据与数据库中的数据一致性,会给 Redis 里的数据设置过期时间,当缓存数据过期后,用户访问的数据如果不在缓存里,业务系统需要重新生成缓存,因此就会访问数据库,并将数据更新到 Redis 里,这样后续请求都可以直接命中缓存。那么,当大量缓存数据在同一时间过期 (失效) 或者 Redis 故障宕机时,如果此时有大量的用户请求,都无法在 Redis 中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃,这就是缓存雪崩的问题。可以看到,发生缓存雪崩有两个原因:大量数据同时过期;Redis 故障宕机;不同的诱因,应对的策略也会不同。大量数据同时过期 针对大量数据同时过期而引发的缓存雪崩问题,常见的应对方法有下面这几种:均匀设置过期时间;互斥锁;双 key 策略;后台更新缓存;1. 均匀设置过期时间 如果要给缓存数据设置过期时间,应该避免将大量的数据设置成同一个过期时间。我们可以在对缓存数据设置过期时间时,给这些数据的过期时间加上一个随机数,这样就保证数据不会在同一时间过期。2. 互斥锁 当业务线程在处理用户请求时,如果发现访问的数据不在 Redis 里,就加个互斥锁,保证同一时间内只有一个请求来构建缓存 (从数据库读取数据,再将数据更新到 Redis 里),当缓存构建完成后,再释放锁。未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。实现互斥锁的时候,最好设置超时时间,不然第一个请求拿到了锁,然后这个请求发生了某种意外而一直阻塞,一直不释放锁,这时其他请求也一直拿不到锁,整个系统就会出现无响应的现象。当用户的请求,都访问数据库的话,请求数量一上来,数据库很容易就奔溃的了,所以为了避免用户直接访问数据库,会用 Redis 作为缓存层。(搜索结果收录于 2026 年 4 月 12 日)

Redis缓存怎么高效用?怎么快速实现高性能数据缓存,解决缓存穿透和雪崩问题?

【黑马点评日记 03】实战:Redis 缓存穿透,缓存击穿,缓存雪崩全解析

前言:前面我们学习了添加商户缓存已经主动更新策略,接下来我们将进行一定的实践,看看如何在实战中实现主动更新,之后就是缓存存在的一些问题:给查询商户的缓存添加超时剔除和主动更新 实现步骤:修改 ShopController 中的业务逻辑,满足下面的需求:根据 id 查询店铺时,如果缓存未命中,则查询数据库,将数据库结果写入缓存,并设置超时时间 代码语言:javascript AI 代码解释 //不存在,查询数据库 Shop shop=getById(id);if(shop==null){return Result.fail("商铺信息不存在");}//写入缓存 stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop),RedisConstants.CACHE_SHOP_TTL,TimeUnit.MINUTES);return Result.ok(shop); 根据 id 修改店铺时,先修改数据库,再删除缓存 代码语言:javascript AI 代码解释 @TransactionalpublicResultupdate(Shop shop){Long id=shop.getId();if(id==null){return Result.fail("店铺 id 不能为空");}//更新数据库 updateById(shop);//删除缓存 stringRedisTemplate.delete(RedisConstants.CACHE_SHOP_KEY+id);return Result.ok();}} 在这里我们使用了事务,因为店铺数据可能涉及多张表 (shop、shop_config、shop_address、shop_audit_log 等) 事务回滚保证这些修改要么全成功,要么全失败 避免出现"店铺名称改了,但配置没改"的中间状态 代码语言:javascript AI 代码解释 时间线:[开启事务]→ [修改 DB 表 1]→ [修改 DB 表 2]→[提交事务]→[删除 Redis 缓存]↑ ↑↑ 事务保证原子性 提交成功才删缓存 可重试 如果 DB 修改失败 → 事务回滚 → 不删缓存 (缓存数据依然正确) 如果 DB 成功但删缓存失败 → 记录日志 → 异步重试删除 缓存穿透:缓存穿透是指:查询一个根本不存在的数据,缓存层和数据库层都没有这个数据。每次请求都会直接穿透缓存,打到数据库上。请求流程:text 代码语言:javascript AI 代码解释 请求→查缓存 (没有)→查数据库 (也没有)→ 返回空 ↑↑ 缓存未命中 每次都查 DB 危害 大量请求直接打到数据库 数据库连接被打满,CPU 飙升 可能引发缓存穿透攻击 (恶意请求大量不存在的 ID) 方案 1:缓存空对象 (最常用) 核心思路:查询不到数据时,缓存一个 null 或特殊标记,设置较短的过期时间。代码语言:javascript AI 代码解释 java @ServicepublicclassShopService{@AutowiredprivateStringRedisTemplate redisTemplate;@AutowiredprivateShopMapper shopMapper;privatestaticfinal StringCACHE_KEY_PREFIX="shop:";privatestaticfinal Long(来自 2026 年 4 月 22 日的资料)

Redis 使用 | 缓存穿透,雪崩,击穿以及解决方案分析

一。什么是 缓存穿透 缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。在流量大时,可能 DB 就挂掉了,要是有人利用不存在的 key 频繁攻击我们的应用,这就是漏洞。小点的单机系统,基本上用 postman 就能搞死,比如我自己买的阿里云服务 像这种你如果不对参数做校验,数据库 id 都是大于 0 的,我一直用小于 0 的参数去请求你,每次都能绕开 Redis 直接打到数据库,数据库也查不到,每次都这样,并发高点就容易崩掉了。缓存穿透解决方案 有很多种方法可以有效地解决缓存穿透问题。1. 最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被 这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力。2. 另外也有一个更为简单粗暴的方法 (我们采用的就是这种),如果一个查询返回的数据为空 (不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。二。什么是 缓存雪崩 我了解的,目前电商首页以及热点数据都会去做缓存,一般缓存都是定时任务去刷新,或者是查不到之后去更新的,定时任务刷新就有一个问题。举个简单的例子:如果所有首页的 Key 失效时间都是 12 小时,中午 12 点刷新的,我零点有个秒杀活动大量用户涌入,假设当时每秒 6000 个请求,本来缓存在可以扛住每秒 5000 个请求,但是缓存当时所有的 Key 都失效了。此时 1 秒 6000 个请求全部落数据库,数据库必然扛不住,它会报一下警,真实情况可能 DBA 都没反应过来就直接挂了。此时,如果没用什么特别的方案来处理这个故障,DBA 很着急,重启数据库,但是数据库立马又被新的流量给打死了。这就是我理解的缓存雪崩。我刻意看了下我做过的项目感觉再吊的都不允许这么大的 QPS 直接打 DB 去,不过没慢 SQL 加上分库,大表分表可能还还算能顶,但是跟用了 Redis 的差距还是很大 同一时间大面积失效,那一瞬间 Redis 跟没有一样,那这个数量级别的请求直接打到数据库几乎是灾难性的,你想想如果打挂的是一个用户服务的库,那其他依赖他的库所有的接口几乎都会报错,如果没做熔断等策略基本上就是瞬间挂一片的节奏,你怎么重启用户都会把你打挂,等你能重启的时候,用户早就睡觉去了,并且对你的产品失去了信心,什么垃圾产品。(2024 年 11 月 4 日)

Redis缓存怎么高效用?怎么快速实现高性能数据缓存,解决缓存穿透和雪崩问题?

FAQ

什么是缓存穿透?

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

Redis缓存怎么高效用?怎么快速实现高性能数据缓存,解决缓存穿透和雪崩问题?

如何解决缓存雪崩?

解决缓存雪崩可以通过均匀设置过期时间,避免大量数据同时过期;使用互斥锁控制并发;采用双 key 策略或二级缓存;以及通过后台更新缓存机制预先加载数据,防止流量瞬间冲击数据库。