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

Redis缓存设计与性能优化指南

Redis缓存设计与性能优化指南


一、缓存穿透

问题描述
查询不存在的数据,缓存和DB均未命中,导致每次请求直达数据库。

原因

  1. 自身业务代码或数据问题
  2. 恶意攻击/爬虫大量请求不存在的数据

解决方案

✅ 缓存空对象
String get(String key) {String cacheValue = cache.get(key);if (StringUtils.isBlank(cacheValue)) {String storageValue = storage.get(key);cache.set(key, storageValue);// 存储值为空时设置短过期时间(300秒)if (storageValue == null) {cache.expire(key, 300);}return storageValue;}return cacheValue;
}
✅ 布隆过滤器(Bloom Filter)
  • 原理:使用位数组+多个无偏哈希函数,判断元素一定不存在或可能存在
  • 特点
    • 适用于数据固定、实时性低的场景
    • 不支持删除操作(需重新初始化)
  • Redisson实现
    RBloomFilter<String> bloomFilter = redisson.getBloomFilter("sample");
    bloomFilter.tryInit(100000L, 0.03);  // 初始化元素量+误判率
    bloomFilter.add("key1");              // 添加数据
    bloomFilter.contains("key1");         // 校验存在性
    

二、缓存击穿(失效)

问题描述
大批量缓存在同一时间失效,导致请求穿透至数据库。

解决方案

// 批量设置缓存时分散过期时间
for (int i = 0; i < items.size(); i++) {int expireTime = 1800 + new Random().nextInt(300); // 1800±300秒cache.set(key, value, expireTime);
}

三、缓存雪崩

问题描述
缓存层崩溃后,流量直接冲击存储层导致级联故障。

解决方案

  1. 高可用架构:使用Redis Cluster/Sentinel
  2. 限流降级
    • 非核心数据:返回预定义空值/错误信息
    • 核心数据(如库存):允许查缓存或DB
  3. 容灾演练:提前模拟缓存宕机场景

四、热点Key重建优化

问题:热点Key失效瞬间,大量线程并发重建缓存。
方案:互斥锁控制重建

String rebuildCache(String key) {String value = cache.get(key);if (value == null) {String lockKey = "lock:" + key;if (lock.tryLock()) {      // 获取分布式锁value = db.get(key);   // 查询数据库cache.set(key, value); // 重建缓存lock.unlock();} else {Thread.sleep(100);     // 等待其他线程完成return cache.get(key); // 重试获取}}return value;
}

五、缓存与DB双写不一致

场景分析

  • 双写不一致:并发写导致数据覆盖
  • 读写不一致:读操作与写操作并发

解决方案

场景策略
低并发数据设置缓存过期时间 + 定期主动更新
允许短暂不一致缓存过期时间兜底
强一致性要求分布式读写锁(如Redisson)
异步监听通过Canal订阅Binlog更新缓存

📌 写多读多且强一致性场景,建议直接读写DB或采用缓存为主存储+DB异步备份。


六、键值设计规范

🔑 Key设计

  • 规范业务名:表名:id(例:trade:order:1
  • 简洁性:控制长度(例:u:{uid}:fr:m:{mid}
  • 禁用字符:空格、换行符、引号等

📦 Value设计

⚠️ 避免BigKey
  • 定义
    • String类型 > 10KB
    • 集合元素 > 5000个
  • 危害
    • 阻塞Redis
    • 网络拥塞
    • 删除操作引发延迟
  • 优化方案
    1. 拆分:大Hash拆分为小Key(例:user:1user:1:info, user:1:orders
    2. 选择合适结构:实体类型用Hash替代多个String
⭐ 最佳实践
  • 设置过期时间:expire key seconds
  • 过期时间打散:避免集中失效

七、命令使用规范

  1. 避免O(N)命令
    • 使用HSCAN/SSCAN替代HGETALL/SMEMBERS
  2. 禁用危险命令
    rename-command KEYS ""
    rename-command FLUSHALL ""
    
  3. 高效批量操作
    • 原生批量命令:MGET/MSET
    • Pipeline非原子操作(一次批量 ≤ 500元素)

八、客户端优化

🔗 连接池配置

参数含义建议值
maxTotal最大连接数按QPS计算(例:QPS=50000 → 50+连接)
maxIdle最大空闲连接maxTotal一致
minIdle最小空闲连接预热连接至该值
testOnBorrow借出时校验高并发设为false

预热连接池示例

List<Jedis> minIdleList = new ArrayList<>(jedisPoolConfig.getMinIdle());
for (int i = 0; i < jedisPoolConfig.getMinIdle(); i++) {Jedis jedis = pool.getResource();minIdleList.add(jedis);jedis.ping(); // 预热连接
}
for (Jedis jedis : minIdleList) {jedis.close(); // 归还连接池
}

九、内存策略优化

♻️ 内存淘汰策略(maxmemory-policy)

策略适用场景
volatile-lru过期Key中淘汰最近最少使用(推荐)
allkeys-lru所有Key中淘汰最近最少使用
volatile-lfu过期Key中淘汰访问频率最低
noeviction不淘汰,拒绝写入(默认)

4.0+版本支持LFU策略,适合热点数据场景。

⚙️ 内核参数调优

# 调整SWAP倾向(避免OOM Kill)
echo vm.swappiness=1 >> /etc/sysctl.conf# 允许内存超分配(保障fork成功)
echo vm.overcommit_memory=1 >> /etc/sysctl.conf# 增加文件句柄数
ulimit -n 65535

十、慢查询监控

# 设置慢查询阈值(单位:微秒)
config set slowlog-log-slower-than 1000  # 保存慢查询日志条数
config set slowlog-max-len 1024  # 查看慢查询日志
slowlog get 5  

📌 生产环境建议阈值设为1ms(1000微秒)


总结:缓存设计的核心在于平衡性能与一致性,避免过度设计。优先解决穿透、雪崩、击穿问题,规范Key设计,警惕BigKey,合理配置连接池和淘汰策略,结合监控实现高性能缓存方案。

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

相关文章:

  • 使用Starrocks替换Clickhouse的理由
  • C++封装、多态、继承
  • 在 Ubuntu 下安装 MySQL 数据库
  • 从文本中 “提取” 商业洞察“DatawhaleAI夏令营”
  • 电路分析基础(02)-电阻电路的等效变换
  • Matlab批量转换1km降水数据为tiff格式
  • 【LeetCode100】--- 5.盛水最多的容器【复习回顾】
  • ssm学习笔记day05
  • QT 多线程 管理串口
  • 《[系统底层攻坚] 张冬〈大话存储终极版〉精读计划启动——存储架构原理深度拆解之旅》-系统性学习笔记(适合小白与IT工作人员)
  • springboot高校竞赛赛事管理系统 计算机毕业设计源码23756
  • Java行为型模式---策略模式
  • 第1章 概 述
  • dll文件缺失解决方法
  • C++——static成员
  • HiPPO: Recurrent Memory with Optimal Polynomial Projections论文精读(逐段解析)
  • QT控件命名简写
  • Linux内核高效之道:Slab分配器与task_struct缓存管理
  • 编译器优化——LLVM IR,零基础入门
  • 学习C++、QT---23(QT中QFileDialog库实现文件选择框打开、保存讲解)
  • 7月13日日记
  • 时间管理四象限理论
  • 小白学Python,操作文件和文件夹
  • 阶段性渗透总结
  • 第五章 Python手写数字识别【CNN卷积神经网络实现】
  • Windows怎样同步时间服务器?
  • 最简约的Windows多标签页文件管理器推荐 - 360文件夹 - 免费开源绿色软件推荐
  • Lucene原理
  • Android自定义View的事件分发流程
  • (33)记录描述窗体组件属性的枚举量 enum Qt :: WidgetAttribute, 简记为 WA_