💥《缓存架构:穿透 / 雪崩 / 击穿解决方案》

文章目录

  • 💥《缓存架构:穿透 / 雪崩 / 击穿解决方案》
  • 🧭 一、开篇导语:为什么缓存是高并发系统的命脉?
    • ✅1.1 缓存的核心价值
      • 缓存带来的收益​​:
    • 💥1.2 缓存不当的灾难
    • 🧨1.3 三大问题导火索
  • 🔍 二、缓存三大核心问题解析与解决方案
    • ✅ 1. 缓存穿透
      • 🛠 解决方案:
    • 💥 2. 缓存击穿
      • 🛠 解决方案:
    • 🧨 3. 缓存雪崩
      • 🛠 解决方案:
  • 🧠 三、进阶架构实践模块
    • 3.1 ✅ 热点 Key 探测与本地缓存
      • ​​实时探测方案​​:
      • Caffeine本地缓存实现​​:
    • 3.2 ✅ Redis 分布式锁的正确实现
      • ​​Redisson最佳实践​​:
    • 3.3 ✅ 多级缓存架构设计
      • ​​三级缓存架构​​:
      • ​​各级缓存配置建议​​:
    • 3.4 ✅ 缓存与数据库一致性
      • ​​​​最终一致性方案​​:
      • Canal + Redis实现​​:
  • 📊四、 总结与实战建议
    • 4.1 不同场景选型建议
    • 4.2 性能优化Checklist
    • 4.3 常见避坑指南
  • 💥 五、互动引导
      • ​​讨论话题​​:

🧭 一、开篇导语:为什么缓存是高并发系统的命脉?

在高并发系统中,缓存是支撑系统性能的关键基石。

  • ✅ 它可减轻数据库压力,显著提升 QPS 和用户体验。

  • 🧨 但一旦缓存失效或设计不当,可能造成雪崩式系统故障。

  • 🧠 三大典型问题:缓存穿透、缓存击穿、缓存雪崩,是系统稳定性的“隐形杀手”。

✅1.1 缓存的核心价值

在这里插入图片描述

缓存带来的收益​​:

  • ​​性能提升​​:Redis QPS可达10万+,远超数据库的5千
  • ​​成本降低​​:减少数据库负载,节省服务器资源
  • ​​​​体验优化​​:响应时间从100ms降至10ms

💥1.2 缓存不当的灾难

​​真实案例​​:某电商大促期间,因缓存雪崩导致:

  • ​​数据库连接池耗尽(1200/1200)
  • ​​响应时间从50ms飙升至15秒
  • ​​订单损失超千万

🧨1.3 三大问题导火索

问题类型触发场景危害等级
​​穿透​​恶意请求不存在数据★★☆
​​击穿​​热点key突然失效★★★
​​雪崩​​大量key同时过期★★★★

🔍 二、缓存三大核心问题解析与解决方案

✅ 1. 缓存穿透

定义:请求数据数据库和缓存中都没有,穿透缓存直接打到数据库。

场景:恶意请求、参数异常、攻击行为。

🛠 解决方案:

在这里插入图片描述

  • 💡 布隆过滤器:初始化时将合法 ID 加入过滤器,拦截非法请求。
// 使用Guava布隆过滤器
BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), 1000000, // 预期元素数量0.01     // 误判率
);// 初始化数据
for (String key : existingKeys) {bloomFilter.put(key);
}// 请求拦截
public Object getData(String key) {if (!bloomFilter.mightContain(key)) {return null; // 直接拦截}// 正常查询流程...
}
  • 🕳️空值缓存:将无数据查询结果短暂缓存,防止重复击打 DB。
if (!bloomFilter.mightContain(id)) {return null; // 拦截非法请求
}
Object data = redis.get(id);
if (data == null) {data = db.query(id);redis.set(id, data == null ? "" : data, 3, TimeUnit.MINUTES); // 空值缓存
}

💥 2. 缓存击穿

定义:热点 Key 失效瞬间,海量请求直接击穿数据库。

典型场景:秒杀商品详情、热点文章页。

🛠 解决方案:

在这里插入图片描述

  • 🔥 热点预加载、缓存永不过期(逻辑失效)
  • 🧱 本地缓存 + 分布式缓存(Caffeine + Redis)组合抗压
  • 🔐 加分布式锁防止缓存同时构建

分布式锁实现​​

public Object getData(String key) {// 1. 先查本地缓存Object value = localCache.get(key);if (value != null) return value;// 2. 查Redisvalue = redisTemplate.opsForValue().get(key);if (value != null) {localCache.put(key, value); // 刷新本地缓存return value;}// 3. 获取分布式锁String lockKey = "lock:" + key;boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "locked", 10, TimeUnit.SECONDS);try {if (locked) {// 4. 再次检查缓存(双检锁)value = redisTemplate.opsForValue().get(key);if (value == null) {// 5. 查询数据库value = dbService.queryData(key);// 6. 写入RedisredisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);}return value;} else {// 等待其他线程加载Thread.sleep(100);return getData(key); // 重试}} finally {if (locked) redisTemplate.delete(lockKey);}
}

🧨 3. 缓存雪崩

定义:大量 Key 在同一时间过期,数据库承压被击穿。

场景:批量缓存设置相同 TTL,集中失效。

🛠 解决方案:

在这里插入图片描述

  • 📊 TTL 加随机抖动,避免同时过期
// 设置缓存时添加随机抖动
int baseTtl = 1800; // 30分钟
int randomTtl = baseTtl + new Random().nextInt(300); // 增加0-5分钟随机值
redisTemplate.opsForValue().set(key, value, randomTtl, TimeUnit.SECONDS);
  • 🧊 分批加载 / 缓存预热
@PostConstruct
public void cacheWarmUp() {List<HotItem> hotItems = dbService.getTop100HotItems();ExecutorService executor = Executors.newFixedThreadPool(4);for (HotItem item : hotItems) {executor.submit(() -> {redisTemplate.opsForValue().set("item:" + item.getId(), item, 30 + new Random().nextInt(10), TimeUnit.MINUTES);});}
}
  • ⚡ 引入熔断降级机制 + 异步缓存重建

🧠 三、进阶架构实践模块

3.1 ✅ 热点 Key 探测与本地缓存

​​实时探测方案​​:

在这里插入图片描述

Caffeine本地缓存实现​​:

LoadingCache<String, Object> localCache = Caffeine.newBuilder().maximumSize(10_000).expireAfterWrite(5, TimeUnit.MINUTES).refreshAfterWrite(1, TimeUnit.MINUTES).build(key -> {// 当本地缓存失效时,从Redis加载return redisTemplate.opsForValue().get(key);});

3.2 ✅ Redis 分布式锁的正确实现

​​Redisson最佳实践​​:

RLock lock = redissonClient.getLock("product_lock:" + productId);
try {// 尝试加锁,最多等待100ms,锁自动释放时间30秒if (lock.tryLock(100, 30, TimeUnit.MILLISECONDS)) {// 执行业务逻辑updateStock(productId);}
} catch (InterruptedException e) {Thread.currentThread().interrupt();
} finally {if (lock.isHeldByCurrentThread()) {lock.unlock();}
}

避免的坑​​:

  1. 非原子操作:setnx + expire 要使用Lua脚本保证原子性
  2. 锁误删:使用唯一value标识锁持有者
  3. 锁续期:使用Redisson的watchdog机制

3.3 ✅ 多级缓存架构设计

​​三级缓存架构​​:

在这里插入图片描述

​​各级缓存配置建议​​:

层级缓存类型TTL特点
L1进程内缓存1-5分钟超高速,容量有限
L2Redis集群30分钟分布式,支持高并发
L3数据库-数据源头,性能最低

3.4 ✅ 缓存与数据库一致性

​​​​最终一致性方案​​:

在这里插入图片描述

Canal + Redis实现​​:

// Canal监听数据库变更
public class CacheInvalidationHandler implements EntryListener {@Overridepublic void onInsert(RowChange rowChange) {String table = rowChange.getTable();List<Column> columns = rowChange.getRow(0).getColumns();if ("products".equals(table)) {String productId = getColumnValue(columns, "id");redisTemplate.delete("product:" + productId);}}
}

📊四、 总结与实战建议

4.1 不同场景选型建议

场景推荐方案注意事项
高并发读多级缓存 + 热点探测监控本地缓存大小
秒杀系统Redis锁 + 本地缓存避免锁竞争过久
数据一致性要求高异步更新 + 重试机制保证最终一致
海量数据布隆过滤器控制误判率

4.2 性能优化Checklist

  1. ​​TTL管理​​:基础值+随机抖动
  2. 预热机制​​:启动时加载热点数据
  3. 监控告警​​:缓存命中率低于90%时报警
  4. 容量规划​​:Redis内存使用不超过70%
  5. ​​大Key治理​​:单Key不超过1MB

4.3 常见避坑指南

在这里插入图片描述

💥 五、互动引导

​​讨论话题​​:

1.你在项目中遇到过哪种缓存问题?如何解决的?
2.对于金融等高一致性场景,如何保证缓存与数据库强一致?
3.本地缓存的最大挑战是什么?

​​欢迎评论区分享你的实战经验!​​ 点赞超过100将更新《Redis深度优化:从大Key治理到集群管理》专题

本文涉及技术栈​​

  • Redis 6.x
  • Spring Boot 3.x
  • Redisson 3.17
  • Caffeine 3.0
  • Canal 1.1.6

​​性能数据来源​​

  • 阿里云Redis性能白皮书
  • 美团缓存架构实践
  • Redis官方基准测试报告

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/914906.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/914906.shtml
英文地址,请注明出处:http://en.pswp.cn/news/914906.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FPGA创意项目网页或博客推荐

1. 综合项目平台(开源+教程) ① Hackster.io - FPGA专区 🔗 https://www.hackster.io/fpga 特点: 大量基于FPGA的创意项目(如Zynq游戏机、视觉处理、机器人控制)。 提供完整教程(Vivado工程文件+代码)。 推荐项目: FPGA-Based Oscilloscope(低成本示波器) V…

Go 程序无法使用 /etc/resolv.conf 的 DNS 配置排查记录

在最近的一次部署中&#xff0c;我遇到一个奇怪的问题&#xff1a;Go 程序在运行时不使用 /etc/resolv.conf 中的 DNS 设置&#xff0c;导致服务无法正常访问域名。这篇文章记录下完整的排查过程和最终的解决方案。1. 问题现象我有一个部署在 KVM 虚拟机内的 Go 应用&#xff0…

微服务相关问题(2)

1、Spring Cloud相关常用组件注册中心&#xff08;nacos、Eureka等&#xff09;、负载均衡&#xff08;Ribbon、LoadBalancer&#xff09;、远程调用&#xff08;feign&#xff09;、服务熔断&#xff08;Sentinel、Hystrix&#xff09;、网关&#xff08;Gateway&#xff09;2…

安全初级2

一、作业要求 1、xss-labs 1~8关 2、python实现自动化sql布尔育注代码优化(二分查找) 二、xss-labs 1~8关 1、准备 打开小皮面板&#xff0c;启动MySQL和apacher 下载 xss-labs&#xff0c;并解压后放到 phpstudy_pro 的 WWW 目录下&#xff0c;重命名为 xss-labs 访问链…

基础算法题

基础算法题 链表 1.1反转链表 描述&#xff1a; 描述 给定一个单链表的头结点pHead(该头节点是有值的&#xff0c;比如在下图&#xff0c;它的val是1)&#xff0c;长度为n&#xff0c;反转该链表后&#xff0c;返回新链表的表头。 数据范围&#xff1a; 0≤&#xfffd;≤…

Android 15 源码修改:为第三方应用提供截屏接口

概述 在 Android 系统开发中,有时需要为第三方应用提供系统级的截屏功能。本文将详细介绍如何通过修改 Android 15 源码中的 PhoneWindowManager 类,实现一个自定义广播接口来触发系统截屏功能。 修改方案 核心思路 通过在系统服务 PhoneWindowManager 中注册自定义广播监…

20250717 Ubuntu 挂载远程 Windows 服务器上的硬盘

由 DeepSeek 生成&#xff0c;方法已经验证可行。 通过网络挂载Windows共享硬盘&#xff08;SMB/CIFS&#xff09; 确保网络共享已启用&#xff1a; 在Windows电脑上&#xff0c;右键点击目标硬盘或文件夹 → 属性 → 共享 → 启用共享并设置权限&#xff08;至少赋予读取权限&…

深度学习图像增强方法(二)

三、直方图均衡化 1. 普通直方图均衡化 直方图均衡化的原理是将图像的灰度直方图展平,使得每个灰度级都有更多的像素分布,从而增强图像的对比度。具体步骤如下: 计算灰度直方图:统计图像中每个灰度级的像素数量。 计算累积分布函数(CDF):计算每个灰度级的累积概率。 映…

QT——信号与槽/自定义信号与槽

1 信号与槽基本介绍 提出疑问&#xff0c;界面上已经有按键了&#xff0c;怎么操作才能让用户按下按键后有操作上的反应呢&#xff1f; 在 Qt 中&#xff0c;信号和槽机制是一种非常强大的事件通信机制。这是一个重要的概念&#xff0c;特别是对于初学者来说&#xff0c;理解它…

Spring原理揭秘--Spring的AOP

在这之前我们已经介绍了AOP的基本功能和概念&#xff0c;那么当AOP集成到spring则会发生改变。Spring AOP 中的Joinpoint&#xff1a;之前提高了很多Joinpoint的类型&#xff0c;但是在spring中则只会有方法级别的Joinpoint&#xff0c;像构造方法&#xff0c;字段的调用都没适…

C++学习笔记五

C继承//基类 class Animal{};//派生类 class Dog : public Animal{};#include<iostearm> using namespace std;//基类 class Shape{public:void setwidth(int w){width w;}void setheight(int h){height h;}protected:int width;int height;}//派生类 class Rectangle …

AndroidStudio环境搭建

一、AndroidStudio下载 正常百度出来的站会自动翻译成中文&#xff0c;导致历史版本的界面总是显示不出可下载的地方&#xff0c;点击成切回英文&#xff0c;就能看出了。 历史版本&#xff1a;https://developer.android.google.cn/studio/archive

Java大厂面试实录:从Spring Boot到AI大模型的深度技术拷问

场景&#xff1a;互联网大厂Java后端面试 面试官&#xff08;严肃&#xff09;&#xff1a;小曾&#xff0c;请坐。今天主要考察Java后端技术栈&#xff0c;包括微服务、大数据、AI等。我们先从简单问题开始。 小曾&#xff08;搓手&#xff09;&#xff1a;好嘞&#xff01;面…

深入解析Hadoop中的HDFS架构设计

HDFS概述与核心设计原则作为Hadoop生态系统的基石&#xff0c;HDFS&#xff08;Hadoop Distributed File System&#xff09;是一种专为大规模数据处理而设计的分布式文件系统。它的核心设计理念源于对互联网时代数据特征的深刻洞察——数据规模呈指数级增长&#xff0c;而硬件…

ota之.加密算法,mcu加密方式

一、ota之.加密算法&#xff0c;mcu加密方式 前面一篇文章&#xff0c;讲了soc的加密方式&#xff0c;但是soc资源充足&#xff0c;mcu没有&#xff0c;所以不会用openss生成公私钥 切计算哈希用rsa256位。 ECC&#xff08;椭圆曲线加密&#xff09; 是一种非对称加密算法&…

LangChain面试内容整理-知识点23:实战案例:检索增强生成(RAG)系统

检索增强生成(Retrieval-Augmented Generation, RAG)是一种将LLM与外部知识库结合的方法,通过实时检索相关信息来辅助生成答案。这极大缓解了LLM“封闭知识”过期或不足的问题。LangChain非常适合构建RAG系统,因为它提供了文档加载、向量存储、检索接口、LLM组合的一站式方…

探索阿里云ESA:开启边缘安全加速新时代

阿里云 ESA 是什么&#xff1f;阿里云 ESA&#xff0c;全称边缘安全加速&#xff08;Edge Security Acceleration&#xff09; &#xff0c;其前身为全站加速 DCDN&#xff08;Dynamic Content Delivery Network&#xff09;。在 2024 年 9 月 30 日&#xff0c;阿里云完成了这…

醋酸铈:赋能科技创新的稀土之力

一、什么是醋酸铈醋酸铈是铈元素与醋酸根离子形成的化合物。铈作为稀土元素中的重要一员&#xff0c;广泛应用于材料科学、催化剂、电子产品等领域。醋酸铈以无色结晶或浅黄色结晶的形式存在&#xff0c;是铈的有机盐之一。它不仅具有稳定的化学性质&#xff0c;而且在某些特定…

数据结构之普利姆算法

前言&#xff1a;Prim算法是图论中的算法&#xff0c;用来生成图的最小生成树。本篇文章介绍算法的流程&#xff0c;实现思想&#xff0c;和具体代码实现&#xff0c;使用c语言。学习需要输出才能理解的更透彻&#xff0c;所以说坚持写文章&#xff0c;希望可以用自己的方式把一…

构建强大的物联网架构所需了解的一切

数据正驱动着当今的商业发展&#xff0c;而物联网&#xff08;IoT&#xff09;则有助于为企业的增长和创新开辟新的机遇。麦肯锡的研究表明&#xff0c;全球数据在四年内实现了惊人的 7 倍增长。随着越来越多的物联网设备进入市场&#xff0c;更多企业开始需要强大的物联网架构…