尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Redis 缓存实战:雪崩、穿透、击穿一次讲透
缓存用好了是性能翻倍用不好凌晨三点把你叫醒。Redis 在大多数系统里扮演的角色是挡在数据库前面的一堵墙。正常情况下请求打到 Redis命中就走数据库压力不大。但这堵墙有三个洞它可能整堵墙同时塌可能有人绕过墙直接锤数据库也可能墙上最忙的那块砖碎了。对应过来就是雪崩、穿透、击穿。一个一个说。一、缓存雪崩整堵墙同时塌了什么是雪崩大量缓存在同一个时间点集中过期所有请求瞬间穿透到数据库数据库扛不住直接挂。典型的触发场景你批量导入了 10 万条商品数据所有缓存都设了 24 小时过期。24 小时后10 万个 key 在同一秒集体死亡。下一秒打进来的请求全部查库数据库连接池瞬间打满。怎么解决三道防线// 防线一过期时间加随机值错开集体死亡 // 不要这样 redisTemplate.opsForValue().set(productKey, value, 24, TimeUnit.HOURS); // 改成这样随机加 1-6 小时 int randomHours ThreadLocalRandom.current().nextInt(1, 7); redisTemplate.opsForValue().set(productKey, value, 24 randomHours, TimeUnit.HOURS); // 防线二永不过期 异步更新 // 缓存本身不设过期由定时任务定期刷新 Scheduled(fixedDelay 300000) // 每5分钟 public void refreshHotProducts() { ListProduct hotProducts productService.getHotProducts(); for (Product p : hotProducts) { String key product: p.getId(); redisTemplate.opsForValue().set(key, p, Duration.ofDays(7)); } } // 注意这里设了7天兜底防止定时任务挂了缓存永远不更新 // 防线三多级缓存 限流兜底 // 如果 Redis 也挂了本地缓存拦截一波 Cacheable(value product, key #id, unless #result null) public Product getProduct(Long id) { return productMapper.selectById(id); } // 数据库层加限流即使被打穿也不至于雪崩到宕机 // Sentinel / RateLimiter 随便选一个核心是保住数据库不挂雪崩的核心矛盾不是数据过期是所有东西同时过期。错开时间就消解了 80% 的风险。二、缓存穿透有人绕过墙直接锤数据库什么是穿透查询一个不存在的数据——缓存里没有数据库里也没有。正常逻辑会直接查库然后发现是空的不写缓存。下次同样的非法请求再来继续查库。恶意攻击者可以构造一大堆不存在的 ID把你的数据库活活打死。// 漏洞代码 public Product getProduct(Long id) { String key product: id; Product p (Product) redisTemplate.opsForValue().get(key); if (p ! null) { return p; } p productMapper.selectById(id); if (p ! null) { redisTemplate.opsForValue().set(key, p, 24, TimeUnit.HOURS); } // BUGp 是 null 的时候什么都不做下次还查库 return p; }怎么修// 方案一缓存空值把「没有」也存起来 public Product getProduct(Long id) { String key product: id; Product p (Product) redisTemplate.opsForValue().get(key); if (p ! null) { // 判断是不是空值标记 if (p.getId() -1L) return null; return p; } p productMapper.selectById(id); if (p null) { // 缓存一个空对象短过期防止被恶意刷 Product empty new Product(); empty.setId(-1L); redisTemplate.opsForValue().set(key, empty, 5, TimeUnit.MINUTES); return null; } redisTemplate.opsForValue().set(key, p, 24, TimeUnit.HOURS); return p; }空值缓存的问题是如果有人刷几百万个不同的非法 IDRedis 内存会被空对象占满。所以// 方案二布隆过滤器事前拦截不存在的 key // 用 Guava 或 Redisson 的布隆过滤器 RBloomFilterString bloomFilter redissonClient.getBloomFilter(product_filter); bloomFilter.tryInit(1000000L, 0.01); // 100万容量1%误判率 // 数据写入时同步加入过滤器 bloomFilter.add(product: id); // 查询前先过过滤器 public Product getProduct(Long id) { String key product: id; if (!bloomFilter.contains(key)) { return null; // 一定不存在直接返回不查库 } // 剩下走正常缓存逻辑 // ... }布隆过滤器的代价有 1% 误判率说存在但实际不存在。多查一次数据库是能接受的。它的价值是拦住 99% 的恶意穿透请求。推荐组合布隆过滤器前置拦截 空值缓存兜底。布隆过滤器拦不住的那 1% 由空值缓存接住。三、缓存击穿墙上最忙的那块砖碎了什么是击穿一个热点 key 过期了这个 key 平时扛几万 QPS。过期瞬间几万请求同时打向数据库。和雪崩的区别是雪崩是一大片 key 同时过期击穿是单个爆款 key 过期。典型场景秒杀商品的库存缓存、首页推荐位的配置缓存、大 V 的粉丝数缓存。// 漏洞代码 public Product getHotProduct(Long id) { String key product: id; Product p (Product) redisTemplate.opsForValue().get(key); if (p null) { // 缓存过期了直接查库 // 几千个线程同时走到这里全部查库 p productMapper.selectById(id); redisTemplate.opsForValue().set(key, p, 10, TimeUnit.MINUTES); } return p; }怎么修// 方案一互斥锁只让一个人去查库 public Product getHotProduct(Long id) { String key product: id; String lockKey lock:product: id; Product p (Product) redisTemplate.opsForValue().get(key); if (p ! null) return p; // SET NX EX抢锁超时 10 秒防止死锁 Boolean locked redisTemplate.opsForValue() .setIfAbsent(lockKey, 1, 10, TimeUnit.SECONDS); if (Boolean.TRUE.equals(locked)) { try { // 抢到锁二次检查 p (Product) redisTemplate.opsForValue().get(key); if (p ! null) return p; p productMapper.selectById(id); redisTemplate.opsForValue().set(key, p, 10, TimeUnit.MINUTES); return p; } finally { redisTemplate.delete(lockKey); } } else { // 没抢到锁等 50ms 重试 try { Thread.sleep(50); } catch (InterruptedException ignored) {} return getHotProduct(id); // 递归重试 } } // 方案二逻辑过期不删 key只更新 value // 适合容忍短期旧数据的场景 public Product getHotProductV2(Long id) { String key product: id; Product p (Product) redisTemplate.opsForValue().get(key); if (p null) { // 首次加载 p productMapper.selectById(id); redisTemplate.opsForValue().set(key, p, 10, TimeUnit.MINUTES); return p; } // 判断是否逻辑过期在 value 里塞一个过期时间戳 if (p.getExpireTime() System.currentTimeMillis()) { // 异步更新当前请求直接返回旧数据 threadPool.submit(() - refreshCache(id)); } return p; // 返回可能过期的旧数据但不会击穿 }逻辑过期方案的关键取舍宁愿用户看到 30 秒前的旧数据也别让他等 5 秒白屏。区别速查表类型现象本质核心解法雪崩大量 key 同时过期过期时间一致随机 TTL 永不过期异步刷新穿透查不存在的 key无缓存屏障布隆过滤器 缓存空值击穿单个热点 key 过期高并发查同一个互斥锁 逻辑过期最后不管你用不用 Redis这三类问题本质上都是同一件事当缓存和数据库之间的假设破裂时你的系统有没有兜底。一个缓存 key 过期了你没有互斥锁说明你假设了缓存永远能命中。缓存不存在你没有布隆过滤器说明你假设了所有请求都是合法的。大量 key 同时过期你没有随机 TTL说明你假设了过期时间是均匀分布的。假设被打破的那一刻就是你的系统开始雪崩的那一刻。
RELATED

相关推荐

计算机组成原理-实验三:从零搭建6116 SRAM读写时序与电路分析

计算机组成原理-实验三:从零搭建6116 SRAM读写时序与电路分析

1. 6116 SRAM芯片基础认知第一次拿到6116这颗芯片时,我盯着24个引脚发了半天呆。作为经典的2K8位静态随机存储器,它就像个微型仓库——能存放2048个8位二进制数。与动态DRAM不同,SRAM不需要刷新电路,这让硬件设计简单不少&#xf…

📅 2026/11/10 9:45:49
C28x DSP平台三相电机SVPWM实时控制代码包(含扇区判断、死区补偿与ePWM适配)

C28x DSP平台三相电机SVPWM实时控制代码包(含扇区判断、死区补偿与ePWM适配)

本文还有配套的精品资源,点击获取 简介:直接用于TI C28x系列DSP(如TMS320F2812、F28335)的三相电机SVPWM生成代码,核心为SVPWM.c文件,纯软件实现空间矢量脉宽调制算法,不依赖外部专用芯片。支…

📅 2026/9/11 17:04:31
模板驱动文档自动化:从静态填空到动态装配的工程实践

模板驱动文档自动化:从静态填空到动态装配的工程实践

1. 项目概述:用模板把文档生产变成“填空题”你有没有过这种体验:每周要交三份客户方案,每份结构雷同——封面、目录、痛点分析、解决方案、报价页、服务承诺——但每次都要从零新建Word、手动调格式、复制粘贴旧内容、反复检查页眉页脚是否错…

📅 2026/10/10 11:24:19
MORE NEWS

更多资讯

📰

电工证应用相关规范保姆级教程:工地太忙根本没时间复习考试怎么办?

电工证应用相关规范保姆级教程:工地太忙根本没时间复习考试怎么办? 工地太忙根本没时间复习考试,这是很多一线电工的真实写照。电工证不仅是上岗的通行证,更是保障安全和提升薪资的关键。随着国家对安全生产和特种作业的规范越来越严格,电工证的应用相关…

📰

深圳宝安区电工证复审怎么搞?电子证书查询全攻略

深圳宝安区电工证复审怎么搞?电子证书查询全攻略 怕考不过白交培训费,这是很多在宝安区做电工的朋友最怕的事。复审流程复杂、资料不全、电子证书查不到,这些都可能让你一不小心就错过了,白花了钱还耽误事。今天就从一个从业多年的老电工角度,告诉你深圳…

📰

深圳宝安区电工证复审怎么搞?工地太忙根本没时间复习考试

深圳宝安区电工证复审怎么搞?工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,这话不是我说的,是深圳宝安区不少电工师傅亲口说的。复审又到了,很多人心里一紧,担心考不过,怕耽误工期,怕被停工罚款,更怕单位因此降薪或辞退。而你要是能提前拿…

📰

北京办电工证考试时间怎么考 官方报名入口在哪里

北京办电工证考试时间怎么考 官方报名入口在哪里 你是不是也担心学历不高报不上电工证?别急,今天我就带你一步步了解【北京办电工证考试时间】和【官方报名入口】在哪里,让你不走弯路,顺利拿下电工证。…

📰

工地太忙根本没时间复习考试,电工证应用相关规范良心建议

工地太忙根本没时间复习考试,电工证应用相关规范良心建议 工地太忙根本没时间复习考试,尤其是像我们这种从其他岗位转岗过来的,手里活儿一堆,脑子里全是工期和进度,压根没空盯着考试题。但如果你正在或打算考电工证,那这些建议你得听进去,因为这证不是…

📰

龙山县电工证考试千万别踩坑,新手如何避开中介陷阱

龙山县电工证考试千万别踩坑,新手如何避开中介陷阱 不知道去哪报名怕被中介坑?龙山县电工证考试千万别踩坑,今天就把那些你可能遇到的坑一针见血说清楚,别再被忽悠了。…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬