news 2026/8/24 3:32:31

redis--006

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
redis--006

1. 缓存穿透

现象

查询缓存、数据库都不存在的数据,大量恶意请求直接打向数据库,压垮 DB。

例:传入不存在的商铺 id,Redis 查不到,每次都去访问数据库。

解决方案

  1. 缓存空值(缓存 null)查询数据库不存在时,把null存入 Redis 并设置短过期时间;后续相同请求直接返回空,不再访问数据库。
  • 优点:简单直接;缺点:会占用少量 Redis 内存。
  1. 布隆过滤器把所有合法数据 ID 预先存入布隆过滤器;请求过来先过过滤器,不合法直接拦截,不去查 Redis 与 DB。适合海量数据场景。
  2. 参数校验:做 ID 格式、范围校验,拦截非法参数;避免 id 被猜测遍历。

业务流程(缓存空值方案)

  1. 根据 id 查询 Redis 缓存
  2. 缓存命中:判断是否为空值,空值直接返回;非空返回业务数据
  3. 缓存未命中:查询数据库
    • 数据库存在:写入真实数据到 Redis,返回数据
    • 数据库不存在:写入 null 空值到 Redis,结束


2. 缓存击穿(热点 Key 问题)

现象

某一个热点高并发的 key 过期失效,大量并发请求同时打到数据库,瞬间冲击 DB。

区别雪崩:击穿是单个热点 key 失效;雪崩是大量 key 集体失效。

两种解决方案对比

表格

方案优点缺点
互斥锁(分布式锁)无额外内存;数据一致性好;实现简单线程等待,性能下降;存在死锁风险
逻辑过期线程不用等待,并发性能高不保证强一致性;消耗内存;业务实现复杂
①互斥锁流程
  1. 请求查询 Redis 缓存,命中直接返回
  2. 缓存未命中,尝试获取分布式互斥锁
    • 获取锁失败:休眠重试,再次查询缓存
    • 获取锁成功:查询数据库,重建缓存写入 Redis,释放锁,返回数据

核心:同一时刻只允许一个线程去数据库重建缓存,其他线程等待重试。

②逻辑过期

不给 key 设置真实 TTL 过期,在 value 内部存一个逻辑过期时间;线程发现逻辑时间过期,开启异步线程更新缓存,旧数据直接返回给用户,不阻塞请求。

@Override public Result queryById(Long id) { //缓存穿透 //解决击穿 Shop shop = queryWithMutex(id); //返回 if (shop == null) { return Result.fail("店铺不存在"); } return Result.ok(shop); } public Shop queryWithMutex(Long id) { String LockKey = null; Shop byId = null; try { //查ID String shopJson = stringRedisTemplate.opsForValue().get("cache:shop" + id); //存在返回,不存在查数据库 if(StrUtil.isNotBlank(shopJson)) { Shop shop = JSONUtil.toBean(shopJson, Shop.class); return shop; } if(shopJson != null) { return null; } //实现缓存重建 LockKey = "lock:shop" + id; boolean isLock = tryLock(LockKey); if (!isLock) { Thread.sleep(50); return queryWithMutex(id); } byId = getById(id); //数据库结果 if (byId == null) { //将空值写入redis stringRedisTemplate.opsForValue().set("cache:shop" + id,"",10, TimeUnit.MINUTES); return null; } stringRedisTemplate.opsForValue().set("cache:shop" + id,JSONUtil.toJsonStr(byId),30, TimeUnit.MINUTES); } catch (InterruptedException e) { throw new RuntimeException(e); } finally { unlock(LockKey); } return byId; } public Shop queryWithPassThrough(Long id) { //查ID String shopJson = stringRedisTemplate.opsForValue().get("cache:shop" + id); //存在返回,不存在查数据库 if(StrUtil.isNotBlank(shopJson)) { Shop shop = JSONUtil.toBean(shopJson, Shop.class); return shop; } if(shopJson != null) { return null; } Shop byId = getById(id); //数据库结果 if (byId == null) { //将空值写入redis stringRedisTemplate.opsForValue().set("cache:shop" + id,"",10, TimeUnit.MINUTES); return null; } stringRedisTemplate.opsForValue().set("cache:shop" + id,JSONUtil.toJsonStr(byId),30, TimeUnit.MINUTES); return byId; } private boolean tryLock(String key) { Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1",10,TimeUnit.MINUTES); return BooleanUtil.isTrue(flag); } private void unlock(String key) { stringRedisTemplate.delete(key); }

3. 缓存雪崩

现象

大量 key 同一时间集体过期,或者 Redis 整体宕机,大量请求绕过缓存全部涌向数据库,数据库压力雪崩。

解决方案

  1. 过期时间添加随机值:TTL 加上随机偏移,打散 key 失效时间,避免集体过期。
  2. Redis 集群高可用:主从、哨兵、集群,避免 Redis 宕机。
  3. 限流 & 降级:网关层限流,服务降级,保护数据库。
  4. 多级缓存:本地 Caffeine 缓存 + Redis 多级缓存,Redis 故障可以兜底。

三者对比总结(面试速记)

表格

问题诱因核心特点
缓存穿透查询根本不存在的数据缓存、数据库都没有该数据
缓存击穿单个热点 key 过期一个热点 key 失效,并发打 DB
缓存雪崩大量 key 同时过期 / Redis 宕机大批量 key 失效,大规模压垮数据库

面试常考区分点:

  • 穿透:查不存在的数据;
  • 击穿:一个热点 key 过期;
  • 雪崩:大批量 key 失效 /redis 挂掉。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/24 3:30:27

Daedalus-150M:专为CPU推理设计的卷积-注意力混合模型解析

你肯定遇到过这种情况:想跑一个最新的开源模型试试效果,结果发现自己的机器要么显存不够,要么压根就没有独立显卡。这时候,要么放弃,要么就得去租用昂贵的云端GPU资源。对于很多个人开发者、学生或者预算有限的小团队来…

作者头像 李华
网站建设 2026/8/24 3:29:59

C/C++结构体从入门到精通:数据封装、内存对齐与工程实践

1. 先搞清楚结构体到底解决什么问题,别急着背语法很多人一上来就翻书看struct怎么定义、怎么声明,结果学了一堆语法,真到写代码的时候还是懵。结构体最核心的价值,是把一堆零散但相关的数据,打包成一个整体来管理。举个…

作者头像 李华
网站建设 2026/8/24 3:26:34

MySQL 慢查询治理:从零搭一套最小可用的索引自动分析脚手架

MySQL 慢查询治理:从零搭一套最小可用的索引自动分析脚手架阅读说明:本文以数据库索引中的典型故障链路说明排查和设计方法。文中的告警、数字与“线上”叙述如未给出来源,均应视为示例条件;落地前请在自己的版本、负载和资源约束…

作者头像 李华
网站建设 2026/8/24 3:25:37

FPGA与MCU通用SPI通信界面设计:从状态机到驱动封装

1. 项目缘起:为什么需要为FPGA和MCU设计一个“通用”SPI界面? 在嵌入式系统开发中,FPGA(现场可编程门阵列)和MCU(微控制器单元)的组合堪称黄金搭档。FPGA擅长并行处理、高速数据流和定制化硬件逻…

作者头像 李华
网站建设 2026/8/24 3:24:11

Lyra 2.0:从文本生成可探索3D世界的混合表示与扩散模型架构详解

最近在探索生成式3D内容领域时,发现许多研究者和开发者都面临一个共同挑战:如何从简单的文本或图像输入,快速、可控地生成一个可供探索的、高质量的3D场景?传统的3D建模流程复杂耗时,而早期的生成式模型又难以保证场景…

作者头像 李华