当前位置: 首页 > ai >正文

redis缓存三大问题分析与解决方案

什么是缓存?

缓存(Cache)是一种将热点数据缓存在内存中(如 Redis)以加快访问速度、减轻数据库压力的技术。

但引入缓存后可能出现 三大核心问题

  • 缓存穿透(Cache Penetration)
  • 缓存击穿(Cache Breakdown)
  • 缓存雪崩(Cache Avalanche)

一、缓存穿透(Cache Penetration)

问题描述

缓存穿透指:请求的数据既不在缓存中,也不在数据库中,导致请求每次都打到数据库

常见场景

  • 恶意攻击:传入大量随机 ID,绕过缓存层直击数据库
  • 用户访问非法 ID,如 /user?id=-1

举例

用户频繁访问一个 不存在的商品 ID:99999999

  • Redis 无此数据 → 查询数据库
  • 数据库无 → 返回 null
  • 下次再次请求 ID=99999999,又重复上述过程 → DB 被压垮

解决方案

1. 缓存空值
if (dbData == null) {redis.set("shop:99999999", "", 2分钟);
}
  • 空值也缓存,避免重复查数据库
  • 设较短 TTL(避免缓存过期数据太久)
2. 参数校验拦截非法请求
  • 如:ID 不能为负数或超过最大值
  • 在请求层面做过滤,不进 DB 或 Redis
3. 布隆过滤器(适用于大数据量)
  • 将所有合法 ID 加入布隆过滤器
  • 请求前先判断是否命中布隆过滤器,不在则直接拒绝

二、缓存击穿(Cache Breakdown)

问题描述

缓存击穿指:某个热点 Key 刚好失效时,大量并发请求打到数据库,导致数据库瞬时压力激增。

常见场景

  • 热点数据正好在高峰期过期
  • 比如:商品详情页、秒杀商品、抢购库存

举例

商品 ID=1 每天百万访问量,缓存过期瞬间,大量用户同时访问导致:

  • Redis 查不到 → 并发查询 DB → 数据库压力飙升

解决方案

1. 互斥锁方式:单线程缓存重建
if (redis.get("shop:1") == null) {if (tryLock("lock:shop:1")) {// 从 DB 读取 → 缓存写回 Redisunlock();} else {// 其他线程等待或返回默认值}
}
  • 缓存重建交给首个拿到锁的线程,其它线程等待或快速失败
2. 逻辑过期 + 异步重建(推荐)
{"data": {...},"expireTime": "2025-06-30 12:00:00"
}
  • 缓存提前设置一个逻辑过期时间(保存在 value 中)
  • 判断已过期 → 异步线程后台刷新 → 返回旧数据不中断用户体验

适合热点数据缓存更新


三、缓存雪崩(Cache Avalanche)

问题描述

大量缓存同时过期,导致所有请求同时访问数据库,引发系统雪崩。

常见场景

  • 设置了相同 TTL 的大量缓存同时过期
  • Redis 重启或崩溃,缓存瞬间全部丢失

举例

  • 秒杀系统中 10 万商品都设置 TTL=24小时
  • 恰好第二天凌晨失效 → 所有请求打到数据库

解决方案

1. 缓存过期时间加随机
int ttl = 3600 + RandomUtil.randomInt(0, 600);
redis.set("shop:" + id, value, ttl, TimeUnit.SECONDS);
  • 避免所有 key 同一时间过期,均匀错开时间点
2. 热点数据永不过期 + 后台异步刷新
  • 逻辑过期方案 + 后台定时更新
  • 热点数据维持高可用
3. 多级缓存(本地 + 分布式)
  • 如:Caffeine + Redis + MySQL 三层缓存
  • Redis 崩溃时,先从本地缓存兜底
4. 限流+降级
  • 接口层加限流、熔断、降级返回默认值,避免雪崩扩大化

项目中 Redis 缓存策略总结

问题定义解决方案
缓存穿透请求数据既不在缓存也不在数据库缓存空值、参数校验、布隆过滤器
缓存击穿热点 key 在高并发下刚好失效加锁互斥、逻辑过期 + 异步刷新
缓存雪崩大量 key 同时过期、或 Redis 故障加 TTL 随机值、热点永不过期、多级缓存、限流降级

实战建议

  • 所有缓存数据 务必设置 TTL,默认不要永久存在
  • 区分冷数据(短 TTL)与热点数据(长 TTL 或逻辑过期)
  • 高并发业务使用异步线程池或消息队列缓冲请求
  • 建立统一的缓存封装组件(CacheClient),集中处理这些问题
http://www.xdnf.cn/news/14762.html

相关文章:

  • 在银河麒麟V10 SP1上手动安装与配置高版本Docker的完整指南
  • 归并排序详解
  • 【网工|知识升华版|实验】4 DHCP原理及应用
  • 数据结构20250620_数据结构考试
  • 南方大暴雨及洪水数据分析与可视化
  • 【Linux】不小心又创建了一个root权限账户,怎么将它删除?!
  • Rust实现FasterR-CNN目标检测全流程
  • 什么是端到端自动驾驶
  • [HDLBits] Cs450/timer
  • Spring MVC详解
  • windows系统下将Docker Desktop安装到除了C盘的其它盘中
  • 力扣 hot100 Day32
  • 毫米波雷达 – 深度学习
  • 腾讯 iOA 零信任产品:安全远程访问的革新者
  • 【仿muduo库实现并发服务器】Channel模块
  • Wireshark TS | 诡异的光猫网络问题
  • rocketmq 之 阿里云转本地部署实践总结
  • MySQL MVCC 详解
  • Linux基本命令篇 —— grep命令
  • jQuery UI 安装使用教程
  • 设置linux静态IP
  • 苹果AR/VR头显路线图曝光,微美全息推进AI/AR智能眼镜新品开启视觉体验篇章
  • 《UE5_C++多人TPS完整教程》学习笔记40 ——《P41 装备(武器)姿势(Equipped Pose)》
  • 为什么js是单线程?
  • 应用场景全解析:飞算 JavaAI 的实战舞台
  • 使用vue开发浏览器chrome插件教程,及之间的消息通信
  • Rust征服字节跳动:高并发服务器实战
  • HarmonyOS应用开发高级认证知识点梳理 (三)状态管理V2装饰器核心规则
  • 端到端 pluto 之数据预处理
  • js代码09