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

Redis缓存穿透、缓存击穿与雪崩防护及性能优化实战指南

封面

Redis缓存穿透、缓存击穿与雪崩防护及性能优化实战指南

在高并发场景中,Redis 作为缓存层可以显著提升系统性能,但也容易出现缓存穿透、缓存击穿和缓存雪崩等问题。本文结合生产环境实战经验,分享完整的防护方案与性能优化方法,提供可运行的代码示例,帮助后端开发者构建高可用、高性能的缓存架构。

目录

  • 业务场景描述
  • 技术选型过程
  • 实现方案详解
    • 缓存穿透防护:布隆过滤器
    • 缓存击穿防护:互斥锁 & 双写模式
    • 缓存雪崩防护:TTL 随机化 & 限流降级
    • 性能优化技巧
  • 踩过的坑与解决方案
  • 总结与最佳实践

一、业务场景描述

某电商系统秒杀服务,核心商品库存信息存储在 MySQL 中。活动期间,瞬时并发请求可达万级,若所有请求直击数据库将导致 DB 崩溃。

  • 请求量:峰值 10,000 QPS
  • 数据热点:少量商品、库存实时变化
  • 系统要求:99% 响应时延 < 50ms

为了满足性能和高可用,缓存层使用 Redis,缓存 key 为 stock:{productId},value 为剩余库存。缓存策略必须防止恶意或异常请求穿透,同时保证缓存失效后快速恢复,并避免短时间内大量失效导致的雪崩。

二、技术选型过程

  1. 缓存穿透防护

    • 方案1:参数校验 + 布隆过滤器
    • 方案2:黑名单 + SQL 缓存
    • 选型:使用布隆过滤器——能够在缓存前有效过滤不存在的 key,内存开销低,误判率可控。
  2. 缓存击穿防护

    • 方案1:互斥锁(分布式锁)
    • 方案2:永不过期的热点缓存
    • 方案3:双写模式(缓存和 DB 同步更新)
    • 选型:互斥锁 + 双写模式:互斥锁保证单线程重建缓存,双写模式则保证 DB 更新及时推送到缓存。
  3. 缓存雪崩防护

    • 方案1:统一 TTL 设置 + 随机化过期时间
    • 方案2:服务降级 + 请求限流
    • 选型:TTL 随机化 + 限流降级:TTL 随机化分散失效压力,限流降级保障核心链路可用。

三、实现方案详解

1. 缓存穿透防护:布隆过滤器

利用布隆过滤器快速判断 key 是否存在,拦截掉大部分无效请求。可选开源实现:Google Guava 或 RedisBloom。

Java 示例(Guava):

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;// 初始化布隆过滤器,预计 1M 元素,误判率 0.01
BloomFilter<Long> bloomFilter = BloomFilter.create(Funnels.longFunnel(), 1_000_000, 0.01);
// 系统启动时将所有有效 productId 添加到过滤器
List<Long> allIds = productService.fetchAllProductIds();
for (Long id : allIds) {bloomFilter.put(id);
}public String handleRequest(Long productId) {if (!bloomFilter.mightContain(productId)) {return error("商品不存在");}// 继续读取缓存或 DB
}

如果使用 RedisBloom:

# 安装模块并开启
MODULE LOAD /path/to/redisbloom.so
BF.RESERVE bf:product 0.01 1000000
BF.ADD bf:product 1001
BF.EXISTS bf:product 1002  # 返回 0 或 1

2. 缓存击穿防护:互斥锁 & 双写模式

  1. 分布式锁(Redisson 实现):
# application.yml
spring:redis:host: redis-cluster.example.comport: 6379password: yourPassword
Config config = new Config();
config.useClusterServers().addNodeAddress("redis://redis1:6379","redis://redis2:6379");
RedissonClient redisson = Redisson.create(config);public String getStock(Long productId) {String key = "stock:" + productId;String val = redisClient.get(key);if (val != null) {return val;}RLock lock = redisson.getLock("lock:stock:" + productId);boolean acquired = lock.tryLock(500, 10000, TimeUnit.MILLISECONDS);if (!acquired) {// 直接返回默认或降级数据return getStockFromDB(productId);}try {// double-checkval = redisClient.get(key);if (val != null) return val;// 从 DB 读取并写入缓存int stock = productService.queryStockFromDb(productId);redisClient.set(key, String.valueOf(stock), 60, TimeUnit.SECONDS);return String.valueOf(stock);} finally {lock.unlock();}
}
  1. 双写模式
  • 在业务更新库存时同时更新缓存:
@Transactional
public void deductStock(Long productId, int amount) {productMapper.updateStock(productId, amount);// 写 DB 后更新缓存int newStock = productService.queryStockFromDb(productId);redisClient.set("stock:"+productId, String.valueOf(newStock), 60, TimeUnit.SECONDS);
}

3. 缓存雪崩防护:TTL 随机化 & 限流降级

  1. TTL 随机化
long baseTtl = 60; // 基础过期时间
long random = ThreadLocalRandom.current().nextLong(0, 30);
redisClient.set(key, value, baseTtl + random, TimeUnit.SECONDS);
  1. 限流降级
  • 前端或网关限流保障核心链路
  • Spring Cloud Gateway 配置示例:
spring:cloud:gateway:routes:- id: seckill_routeuri: lb://seckill-servicepredicates:- Path=/seckill/**filters:- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 1000redis-rate-limiter.burstCapacity: 200

4. 性能优化技巧

  • 使用管道(Pipeline)或批量操作减少 RTT。
  • 客户端连接池配置:
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(50);
poolConfig.setMaxIdle(10);
poolConfig.setMinIdle(5);
JedisPool jedisPool = new JedisPool(poolConfig, "redis-host", 6379, 2000, "pwd");
  • 监控指标:使用 Prometheus + Grafana 监控 used_memory_rssinstantaneous_ops_per_sec 等。

四、踩过的坑与解决方案

  1. 布隆过滤器误判率配置过高,导致大量合法请求被拦截

    • 解决:增大过滤器容量或降低误判率参数,线上定期全量重建。
  2. 分布式锁释放异常未解锁,造成请求雪崩

    • 解决:使用 Redisson 自带锁,设置 leaseTime 自动过期,避免死锁。
  3. TTL 随机化不够,仍有热点失效同时触发

    • 解决:将随机区间扩大至基础 TTL 的 50% ~ 150%,并结合限流。
  4. Lua 脚本执行阻塞 Redis 主线程

    • 解决:把脚本优化为无阻塞、逻辑简洁的原子操作,或使用 Redis 集群隔离压力。

五、总结与最佳实践

  • 前置过滤(布隆过滤器)能够高效拦截非法请求,减少后端压力。
  • 互斥锁 + 双写模式确保缓存击穿时只有一个线程回源并快速恢复缓存。
  • TTL 随机化与限流降级结合使用,避免缓存雪崩并保证核心链路可用。
  • 结合监控与告警体系,持续观察缓存命中率/Redis 关键指标,及时调整参数。
  • 在大并发场景下,Redis 操作请尽量使用 pipeline、批量或 Lua 脚本保证原子性。

至此,完整的 Redis 高可用缓存防护与性能优化实战方案分享完毕,欢迎在生产环境中实践并持续改进。


作者:匿名


文章转载自:

http://5Jau3Sv2.mpwgs.cn
http://3Puhvg6v.mpwgs.cn
http://uZdZaYEe.mpwgs.cn
http://EhMPUN2Z.mpwgs.cn
http://hdqVcdPf.mpwgs.cn
http://XNmYlBMg.mpwgs.cn
http://p6nFzjkl.mpwgs.cn
http://cBNychUf.mpwgs.cn
http://xzesHHRy.mpwgs.cn
http://TtSOPo1I.mpwgs.cn
http://bUQONCUU.mpwgs.cn
http://qAEiLAdI.mpwgs.cn
http://rTcn1OkQ.mpwgs.cn
http://jq9uHvmb.mpwgs.cn
http://VsuH84Qc.mpwgs.cn
http://o5amlSU5.mpwgs.cn
http://6WevqkMp.mpwgs.cn
http://esMA4YgC.mpwgs.cn
http://eFQJI22E.mpwgs.cn
http://FhPPgTJi.mpwgs.cn
http://CpyhIvGl.mpwgs.cn
http://fH2kRPJK.mpwgs.cn
http://MSCSNvJU.mpwgs.cn
http://XAWCV7lw.mpwgs.cn
http://Pv73YwIt.mpwgs.cn
http://V6Teo0KP.mpwgs.cn
http://gkJSBd9k.mpwgs.cn
http://fqFeHlKY.mpwgs.cn
http://pKHPlz32.mpwgs.cn
http://SCEdmY25.mpwgs.cn
http://www.dtcms.com/a/374584.html

相关文章:

  • ArcGIS学习-20 实战-地形研究
  • Ubuntu下基于Nginx+ffmpeg+video.js的HLS流媒体视频播放方案
  • Vue2 VS Vue3
  • 【ArcGIS】如何编辑图层的属性表
  • VueFlow的箭头怎么调整
  • 基于Vue3 +ElementuiPlus + Dexie.js自研的浏览器插件新建标签页tab
  • 【序列晋升】30 Spring Cloud Vault 安全配置管理的微服务守护者
  • 狂想-一种新颖的低成本内嵌标记的视触觉感知前导方案
  • 兰洋科技双展联动展示液冷创新成果,技术驱动打造绿色算力新基建
  • INDEMIND亮相2025科技创变者大会,以机器人空间智能技术解锁具身智能新边界
  • 百度SEM里什么是搜索广告、搜索词、否定关键词、上方位(竞价)广告?
  • 百度竞价推广:百度搜索竞价推广代运营
  • rabbitmq如何保证消息不丢失
  • 做百度SEM付费搜索推广时,竞价账号定向怎么设置?
  • html+css+JavaScript实现一个简单的登录
  • 【国内电子数据取证厂商龙信科技】从SQL语句开始数据库分析
  • 字节跳动Seed推出「机器人大脑」Robix:让机器人学会思考、规划与灵活互动
  • 【ComfyUI】Flux Schnell Fp8量化版图像生成
  • 【3DV 进阶-2】Hunyuan3D2.1 训练代码详细理解下-数据读取流程
  • 从零开始的云计算生活——第六十天,志在千里,使用Jenkins部署K8S
  • 平板热点频繁断连?三步彻底解决
  • nand flash的擦除命令使用
  • 《Pod调度失效到Kubernetes调度器的底层逻辑重构》
  • OC-单例模式
  • C语言链表设计及应用
  • 中级统计师-统计法规-第三章 统计法的基本原则
  • 【VR音游】音符轨道系统开发实录与原理解析(OpenXR手势交互)
  • web前端安全-什么是供应链攻击?
  • Saucony索康尼推出全新 WOOOLLY 运动生活羊毛系列 生动无理由,从专业跑步延展运动生活的每一刻
  • 后端(FastAPI)学习笔记(CLASS 2):FastAPI框架