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

【Redis】 缓存三大问题 + 大Key/热Key 全面解析

大家好,我是程序员二叉。


简介

本文详解缓存穿透、缓存击穿、缓存雪崩三大经典问题,同时讲解 Redis 大 Key、热 Key 的成因与解决方案,包含原理、场景、实操方案与业界落地思路,适合面试复盘与项目实战。欢迎点赞收藏关注。


一、缓存穿透

1. 定义

查询数据库和缓存中都不存在的数据,请求直接绕过缓存,持续打到数据库,造成数据库压力陡增,称之为缓存穿透

2. 产生原因

  1. 恶意攻击:攻击者批量请求不存在的非法 ID、乱造参数。
  2. 业务异常:前端传参错误、爬虫遍历无效数据。
  3. 空数据未处理:不存在的数据没有做缓存兜底。

3. 四种解决方案

方案1:缓存空值(空对象/空字符串)
  • 思路:查询数据库发现数据不存在时,依然向 Redis 写入一个空标记,并设置较短过期时间。
  • 优点:实现简单、成本低。
  • 缺点:会占用 Redis 内存;短时间大量无效 key 仍会堆积。
方案2:布隆过滤器
  • 思路:提前将数据库所有合法主键/有效参数存入布隆过滤器。请求进来先校验过滤器,判定不存在则直接拦截,不访问缓存与数据库。
  • 优点:内存占用极小,拦截效率高,适合海量数据场景。
  • 缺点:存在误判;不支持数据删除(传统布隆过滤器);数据更新需同步维护过滤器。
方案3:接口层参数校验与限流
  • 思路:在网关/接口层做前置拦截,校验参数合法性(ID 格式、范围、黑名单);对异常 IP、高频请求做限流、封禁。
  • 优点:从入口拦截恶意请求,通用性强。
  • 缺点:无法防范正常参数下的穿透问题。
方案4:设置互斥空缓存 + 延时淘汰
  • 思路:结合分布式锁,避免同一无效参数并发穿透;空值设置较短过期时间,定期清理无效 key,控制内存占用。
  • 适用:中小型业务,兼顾性能与内存。

组合建议:参数校验 + 布隆过滤器作为主流方案;中小项目可直接使用「缓存空值」快速落地。


二、缓存击穿

1. 定义

热点 Key 在缓存过期瞬间,大量并发请求同时涌入,全部打到数据库,该现象称为缓存击穿。
特点:只针对单个热点 Key,区别于雪崩的批量失效。

2. 产生原因

  1. 热点商品、热搜数据等访问量极高的 Key,设置了统一过期时间。
  2. Key 过期一瞬间,海量并发请求绕过缓存直达数据库。

3. 解决方案

方案1:热点数据永不过期(物理永不过期)
  • 思路:对核心热点 Key不设置过期时间,从根源避免过期击穿。
  • 补充:业务更新数据时,主动更新 Redis 缓存,保证数据一致性。
  • 优点:实现最简单,无并发问题。
  • 缺点:数据长期驻留内存,需手动维护更新;仅适合变更频率低的热点数据。
方案2:加分布式互斥锁
  • 思路:缓存失效后,只允许一个请求去查询数据库并更新缓存,其他请求等待重试。
  • 实现:使用 RedisSET NX EX实现分布式锁。
  • 执行流程:
    1. 查缓存,不存在则尝试加锁;
    2. 加锁成功 → 查询数据库,回写缓存,释放锁;
    3. 加锁失败 → 短暂休眠后重试查缓存。
  • 优点:通用性强,所有场景均可使用。
  • 缺点:会产生少量等待,并发极高时存在性能损耗;需处理锁超时、死锁问题。
拓展方案:逻辑过期(常用优化)
  • 不删除 Key,在 Value 中额外存储逻辑过期时间
  • 线程发现逻辑过期后,通过异步线程更新缓存,旧数据继续对外提供服务。
  • 优点:无等待、吞吐量高;缺点:会短暂存在数据不一致。

三、缓存雪崩

1. 定义

大量缓存 Key 在同一时刻集体失效,或 Redis 服务宕机,导致海量请求全部压向数据库,数据库压力过载甚至宕机,连锁引发整个系统崩溃,即为缓存雪崩。

2. 产生原因

  1. 批量 Key过期时间集中,同一时间大面积失效。
  2. Redis 集群宕机、断电、网络故障,缓存整体不可用。
  3. 缓存服务性能瓶颈、响应超时,等同于缓存失效。

3. 全流程解决方案(事前 + 事中 + 事后)

(1)事前预防(优先做,成本最低)
  1. 过期时间加随机值
    给缓存过期时间增加随机偏移量,打散过期时间,避免集体失效。例:基础时长 + 0~300秒随机值
  2. Redis 高可用架构
    搭建主从 + 哨兵或 Redis 集群,避免单节点宕机导致整体不可用。
  3. 热点数据永不过期
    核心流量数据禁用过期时间,从源头规避失效风险。
(2)事中管控(故障发生时止损)
  1. 接口限流 & 熔断降级
    网关/服务层使用限流组件,限制每秒请求量;缓存失效触发大量慢查询时,开启熔断,直接返回兜底数据,不再访问数据库。
  2. 多级缓存
    引入本地堆缓存(Caffeine、Guava)+ 分布式缓存 Redis,多层兜底,降低 Redis 压力。
  3. 分布式锁限流
    针对失效缓存做请求排队,控制访问数据库的并发量。
(3)事后恢复(故障发生后快速修复)
  1. 快速重启/切换节点
    Redis 宕机后,依靠哨兵自动切换主节点,快速恢复缓存服务。
  2. 缓存预热
    手动/脚本批量重建热点缓存,避免恢复瞬间再次被打垮。
  3. 故障复盘
    排查宕机、超时原因,优化架构与参数,防止重复发生。

四、Redis 大 Key 问题

1. 什么是大 Key

  • 字符串类型:Value 体积过大(通常建议 >10KB 判定为大 Key)。
  • 集合类型(List/Hash/Set/ZSet):元素数量极多(如 Hash 字段上千、List 元素过万)。

2. 危害

  1. 网络传输耗时增加,接口响应变慢。
  2. 内存分配、数据迁移(集群分片)卡顿,阻塞 Redis 主线程。
  3. 删除大 Key 会产生大量内存释放耗时,引发服务阻塞。

3. 核心解决方案(核心思路:拆分)

  1. 横向拆分(分 Key 存储)
    将一个大 Key 拆分为多个小 Key。例如:海量用户列表,按 ID 哈希分段拆分。
  2. 纵向拆分(字段拆分)
    针对 Hash 类型,将不常访问的字段拆到独立 Key,减少单个 Hash 体量。
  3. 控制元素数量
    限制 List/Set/ZSet 最大元素个数,超出则分页存储。
  4. 渐进式删除
    禁止直接DEL大 Key,使用hscan/lscan分批遍历删除,避免阻塞主线程。
  5. 优化数据结构
    合理选用结构,避免盲目使用集合类型存储海量数据。

五、Redis 热 Key 问题

1. 什么是热 Key

某一个 Key 被超高并发访问(每秒数万/十万次请求),流量集中在单个 Key,造成 Redis 单节点压力过载、网卡打满、请求延迟升高。
常见场景:秒杀商品、首页活动、全网热搜。

2. 产生危害

  1. Redis 单节点 CPU、网卡、连接数打满,影响其他正常 Key。
  2. 集群环境下,流量倾斜,分片负载严重不均。

3. 主流解决方案(含京东 HotKey 探测机制)

基础通用方案
  1. 本地缓存兜底
    在应用层增加堆内本地缓存(Caffeine),拦截大部分热点请求,不打到 Redis。设置短过期时间,兼顾一致性与性能。
  2. Key 分片(复制热点)
    将一个热 Key 复制为多个名称不同、数据相同的 Key,分散到集群不同节点,分摊流量。请求时随机路由到其中一个分片 Key。
  3. 请求限流 & 排队
    接口层对热 Key 做限流、队列削峰,降低并发压力。
业界方案:京东 HotKey 探测与防护机制

京东自研 HotKey 组件,分为探测、上报、兜底三部分:

  1. 热 Key 实时探测
    • 客户端/代理层(Proxy)统计每个 Key 的 QPS,基于滑动窗口统计访问频率。
    • 超过预设阈值则判定为热 Key,实时上报至统一控制台。
  2. 全局热 Key 汇总
    收集全集群上报的热点 Key,形成全局热 Key 清单,同步至所有服务节点。
  3. 多层缓存兜底
    • 识别到热 Key 后,自动将数据加载到应用本地缓存,优先走本地缓存。
    • 动态调整分片、自动复制热 Key,打散集群流量。
  4. 流量监控与告警
    热 Key 持续高位时触发告警,运维介入人工优化。
补充优化
  • 热点数据禁止复杂命令,只使用简单读写命令。
  • 集群合理分片,避免热点固定落在单一节点。

总结

  1. 缓存穿透:查不存在的数据 → 方案:缓存空值、布隆过滤器、参数校验、分布式空缓存。
  2. 缓存击穿:单个热点 Key 过期 → 方案:互斥分布式锁、数据永不过期、逻辑过期。
  3. 缓存雪崩:大量 Key 同时失效/缓存宕机 → 事前打散过期时间、高可用;事中限流熔断、多级缓存;事后快速恢复、缓存预热。
  4. 大 Key:核心解决思路为拆分 + 分批删除,控制单 Key 数据量。
  5. 热 Key:本地缓存、Key 分片分流;业界参考京东 HotKey 做实时探测、全局感知、多层兜底。
http://www.jsqmd.com/news/932702/

相关文章:

  • 实战OpenCV与Python:如何用代码获取和验证你的相机内参矩阵K?
  • Arduino Mega 2560异步编程实战:多任务、中断与状态机应用
  • 华为OD算法复习5——栈与队列 Javascript
  • 3步完成Mac Boot Camp驱动自动化安装:Brigadier终极解决方案
  • 如何快速免费下载Sketchfab完整3D模型?终极简单指南
  • 别再踩坑了!AI智能体选型避坑指南,这款神器让你少花冤枉钱
  • 小程序样式适配深坑!iOS/Android样式错乱终极解决方案
  • 2026年GEO商业模式的本质困境:为什么大多数服务商难以盈利?
  • LIWC-Python 终极指南:用Python解锁文本心理学的秘密
  • 常见的网络攻击
  • 从啤酒尿布到你的购物车:用亲和性分析优化独立站商品推荐(Python实战)
  • 告别启动失败:微PE装Win10/Win11时,关于Legacy和UEFI引导你必须知道的几件事
  • 基于GSR与PPG传感器的嵌入式生理信号检测系统开发实践
  • 用74HC595驱动4位数码管:3个引脚实现32段显示的动态扫描方案
  • XCOM 2 Alternative Mod Launcher 终极指南:告别官方启动器的完整解决方案
  • 5大维度深度解析OneMore:重塑OneNote生产力的开源插件
  • 每日 AI 研究简报 · 2026-05-31
  • FigmaCN:3分钟搞定Figma中文界面汉化的完整指南
  • 2026年做水力计算的公司价格排名,哪家性价比高? - myqiye
  • 智慧树自动刷课插件:告别手动点击,让学习回归本质
  • AI在PPT制作中的应用
  • 告别A/B测试?用Python+Ray手把手实现Thompson Sampling,搞定多臂老虎机问题
  • 告别ArcGIS频繁崩溃:从Normal.mxt到Python环境,彻底排查那些不起眼的配置陷阱
  • 专业WarcraftHelper完整指南:魔兽争霸III游戏优化工具一键配置
  • Arduino与伺服电机DIY动态万圣节鬼屋:从原理到实现的创客指南
  • 暗黑2存档编辑器终极指南:免费Web工具5分钟快速修改D2/D2R游戏存档
  • 如何彻底禁用Windows Defender:开源工具Defender Control技术深度解析
  • TVS选型与电路防护:从浪涌机理到钳位优化的完整指南
  • 字节跳动面试全解析:算法与工程双核心
  • AI英语教育系统的开发方案