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

Redis缓存三兄弟:穿透、击穿、雪崩全解析

缓存三兄弟

1. 缓存穿透

定义:查询一个不存在的数据,缓存中没有,数据库中也没有,导致每次请求都直接打到数据库。

危害:恶意攻击者可以利用这个漏洞,大量请求不存在的数据,导致数据库压力过大。
缓存穿透

解决方案

  • 缓存空对象:将空结果也缓存起来,但要设置较短的过期时间,避免数据不一致
  • 布隆过滤器:在缓存之前增加一层布隆过滤器,快速判断数据是否可能存在
    • 原理:通过多个哈希函数将数据映射到位数组中,查询时判断对应位置是否都为1
    • 特点:可能存在误判(说存在但实际不存在),但不会漏判(说不存在就一定不存在)
    • 实现:可使用Redisson或Guava的布隆过滤器
      布隆过滤器

2. 缓存击穿

定义:某个热点key过期时,大量并发请求同时访问这个key,导致请求直接打到数据库。
缓存击穿

解决方案

  • 互斥锁

    • 优点:强一致性,确保只有一个线程查询数据库
    • 缺点:性能较差,其他线程需要等待
      互斥锁
  • 逻辑过期

    • 实现:不设置Redis过期时间,在value中存储逻辑过期时间
    • 优点:高可用性,性能优秀
    • 缺点:可能会返回过期数据,最终一致性

逻辑过期

3. 缓存雪崩

定义:大量缓存key在同一时间失效,或Redis服务宕机,导致大量请求直接打到数据库。
缓存雪崩

解决方案

  • 随机过期时间:给不同key的TTL添加随机值,避免同时过期
  • Redis集群:提高服务可用性,避免单点故障
  • 限流降级:在缓存大量失效时,对请求进行限流和降级处理
  • 多级缓存:建立多层缓存架构,如本地缓存+Redis+数据库

缓存一致性问题

双写一致性

定义:当修改数据库数据时,需要同时更新缓存数据,保持缓存和数据库数据一致。

解决方案

1. 异步通知方案(适用于允许延时一致的业务)

基于MQ消息队列

  • 更新数据库后,发送MQ消息通知缓存删除
  • 优点:解耦、可靠性高
  • 缺点:有延时,可能出现短暂的数据不一致
    基于MQ消息队列

基于Canal的异步通知

  • Canal伪装成MySQL的从节点,通过读取binlog来更新缓存
  • 优点:无需修改业务代码,对业务无侵入
  • 缺点:依赖binlog,有一定的技术复杂度
    基于Canal的异步通知
2. 强一致性方案

Redisson读写锁

  • 共享锁(读锁):多个线程可以同时获取读锁,进行读操作
  • 排他锁(写锁):只有一个线程可以获取写锁,阻塞其他线程的读写操作

读操作流程

  1. 尝试获取读锁
  2. 缓存命中直接返回
  3. 缓存未命中查询数据库
  4. 将结果写入缓存并设置过期时间
  5. 释放读锁

写操作流程

  1. 获取写锁
  2. 先删除缓存
  3. 更新数据库
  4. 延迟删除缓存(延迟双删)
  5. 释放写锁
3. 延迟双删策略

为什么需要延迟双删

  • 先删缓存再更新数据库:并发读请求可能在数据库更新前查询到旧数据并写入缓存
  • 先更新数据库再删缓存:并发读请求可能在缓存删除前查询到旧数据

延迟双删流程

  1. 删除缓存
  2. 更新数据库
  3. 延迟N秒后再次删除缓存(N通常为读操作的耗时)

Redis持久化

RDB(Redis Database)

  • 原理:在指定时间间隔内将内存中的数据集快照写入磁盘
  • 优点:文件紧凑,恢复速度快,对性能影响小
  • 缺点:可能丢失两次快照间的数据

AOF(Append Only File)

  • 原理:记录每个写操作,重启时重新执行这些命令来恢复数据
  • 优点:数据安全性高,可以做到秒级数据丢失
  • 缺点:文件体积大,恢复速度慢

建议:生产环境同时开启RDB和AOF,确保数据安全性。

面试要点总结

  1. 缓存三兄弟:穿透、击穿、雪崩的区别和解决方案要熟练掌握
  2. 一致性策略:根据业务需求选择合适的一致性方案
  3. 读写锁:理解共享锁和排他锁的区别和应用场景
  4. 延迟双删:理解为什么需要延迟双删,以及如何确定延迟时间
  5. 持久化:了解RDB和AOF的特点和适用场景

记住:没有完美的解决方案,只有最适合当前业务场景的方案。面试时要结合具体业务场景来回答问题。

http://www.dtcms.com/a/275218.html

相关文章:

  • 张量与维度
  • Grid网格布局完整功能介绍和示例演示
  • 2023年全国青少年信息素养大赛C++编程初中组决赛真题+答案解析
  • RestTemplate动态修改请求的url
  • 第一周JAVA——选择结构、循环结构、随机数、嵌套循环、数组(一维、二维)、方法、形参实参
  • 《每日AI-人工智能-编程日报》--7月11日
  • python知识:正则表达式快速入门案例:提取文章中所有的单词、提取文章中所有的数字、提取百度热搜的标题、提取ip地址
  • Web攻防-SSTI服务端模版注入利用分类语言引擎数据渲染项目工具挖掘思路
  • Umi-OCR 的 Docker安装(win制作镜像,Linux(Ubuntu Server 22.04)离线部署)
  • 数据集相关类代码回顾理解 | StratifiedShuffleSplit\transforms.ToTensor\Counter
  • 数据结构-双链表
  • 数字产品的专利战:要么布局称王,要么维权忙?
  • ABP VNext + Microsoft YARP:自定义反向代理与请求路由
  • 文件上传漏洞1-文件上传漏洞详细原理讲解与利用方式
  • 设计模式 - 面向对象原则:SOLID最佳实践
  • scrapy框架
  • 源表=电源+数字表?一文看懂SMU源表 2025-04-14
  • 大模型开发框架LangChain之函数调用
  • linux常用命令(一)
  • cnas实验室高效获证路径,cnas认证常见失败原因?
  • Linux711 Mysql
  • 使用node调用jira接口
  • [精选]如何解决pip安装报错ModuleNotFoundError: No module named ‘subprocess’问题
  • linux系统-----Redis主从复制
  • 生成对抗网络(GAN)原理详细讲解
  • MoE混合专家模型:千亿参数的高效推理引擎与架构革命
  • python文件操作与正则表达式综合练习
  • 第三方渗透测试:范围咋定?需供应商同意吗?
  • 【经典面经】C++新特性 TCP完整收发数据 TLS1.2 TLS1.3
  • 低成本的AI知识库方案及推荐