如何排查Redis单个Key命中率骤降?

问题现象

Redis整体命中率98%,但监控发现特定Key(如user:1000:profile)的命中率从99%骤降至40%,引发服务延迟上升。

排查步骤
1. 确认现象与定位Key
// 通过Redis监控工具获取Key指标
public void monitorKey(String key) {Jedis jedis = new Jedis("localhost");// 使用Redis命令分析Key访问模式System.out.println("Key访问统计: " + jedis.objectEncoding(key));System.out.println("Key剩余TTL: " + jedis.ttl(key) + "秒");
}
  • 使用redis-cli --hotkeysmonitor命令确认Key访问频率
  • 检查监控系统(如Grafana)观察命中率下降时间点
2. 检查业务变更
// 检查新上线代码:缓存读写逻辑是否变化
@Service
public class UserService {// 变更前代码:正常缓存读取@Cacheable(value = "userProfile", key = "#userId")public User getProfile(Long userId) { /* 查数据库 */ }// 变更后问题代码:错误覆盖了缓存Keypublic void updateProfile(Long userId) {userDao.update(userId);// 错误:未清除旧缓存,直接写入新KeyredisTemplate.opsForValue().set("user_profile_" + userId, newData); }
}
  • 排查点:
    • 是否新增绕过缓存的直接DB查询?
    • Key生成规则是否改变(如user:{id}user_profile_{id})?
    • 缓存清理逻辑是否遗漏(如@CacheEvict注解缺失)
3. 分析缓存失效策略
// 检查TTL设置:确认是否设置过短
@Configuration
public class RedisConfig {@Beanpublic RedisCacheManager cacheManager(RedisConnectionFactory factory) {RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()// 问题点:全局设置10分钟TTL.entryTtl(Duration.ofMinutes(10)); return RedisCacheManager.builder(factory).cacheDefaults(config).build();}
}
  • 关键问题:
    • TTL设置不合理:热点Key过期时间过短
    • 批量失效:定时任务导致关联Key集中清除
    • 内存淘汰策略:检查maxmemory-policy是否主动删除Key
4. 验证数据一致性
// 典型缓存不一致场景:先更库后删缓存失败
public void updateUser(Long userId) {// 步骤1:更新数据库userDao.update(userId);// 步骤2:删除缓存(可能失败)try {redisTemplate.delete("user:" + userId);} catch (Exception e) {// 未处理异常导致缓存未删除!logger.error("缓存删除失败", e);}
}
  • 一致性陷阱:
    • 缓存穿透:恶意请求不存在的Key(如user:-1
    • 缓存击穿:热点Key失效瞬间大量请求穿透
    • 更新顺序:DB更新成功但缓存删除失败
针对性解决方案
方案1:缓存穿透 → 空值缓存
public User getProfile(Long userId) {String key = "user:" + userId;User user = redisTemplate.opsForValue().get(key);if (user == null) {user = userDao.findById(userId);// 缓存空值防止穿透redisTemplate.opsForValue().set(key, user != null ? user : "NULL", 5, TimeUnit.MINUTES);}return "NULL".equals(user) ? null : user;
}
方案2:缓存击穿 → 互斥锁
public User getProfileWithLock(Long userId) {String key = "user:" + userId;User user = redisTemplate.opsForValue().get(key);if (user == null) {String lockKey = "lock:" + key;if (redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 30, TimeUnit.SECONDS)) {try {user = userDao.findById(userId); // 查DBredisTemplate.opsForValue().set(key, user, 1, TimeUnit.HOURS);} finally {redisTemplate.delete(lockKey); // 释放锁}} else {// 其他线程等待重试Thread.sleep(50);return getProfileWithLock(userId);}}return user;
}
方案3:一致性保障 → 双删策略
public void updateUser(Long userId) {// 1. 先删缓存redisTemplate.delete("user:" + userId); // 2. 更新数据库userDao.update(userId); // 3. 延时二次删除(应对主从延迟)executor.schedule(() -> {redisTemplate.delete("user:" + userId);}, 1, TimeUnit.SECONDS); 
}
预防措施
  1. 监控预警
    • 对核心Key设置命中率阈值告警(如<90%触发)
    • 日志记录缓存删除失败操作
  2. 架构优化
    • 使用Redisson实现分布式锁
    • 采用Caffeine实现本地二级缓存
  3. 策略配置
    # Redis配置调整
    config set maxmemory-policy allkeys-lru  # 内存不足时LRU淘汰
    config set notify-keyspace-events Ex    # 订阅Key过期事件
    

经验总结:80%的命中率下降源于业务变更和失效策略不当。通过代码审查 + 实时监控 + 防御性编程,可快速定位并解决此类问题。

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

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

相关文章

自定义Shell命令行解释器

目录 1、目标 2、显示命令提示符 2.1 getenv 2.2 getcwd 2.3 putenv 3、获取用户输入的命令 4、解析命令 5、处理内建命令 6、处理外部命令 7、完整代码 7.1 myshell.cpp 7.2 Makefile 1、目标 实现一个Linux的myshell&#xff0c;有以下基本的功能。 显示命令提示…

Laplace 噪声

Laplace 噪声是一种特定概率分布&#xff08;拉普拉斯分布&#xff09;产生的随机扰动。它是差分隐私&#xff08;Differential Privacy, DP&#xff09;中最核心、最常用的噪声机制之一。它的核心作用是在不泄露个体信息的前提下&#xff0c;允许从包含敏感数据的数据库中提取…

基于空天地一体化网络的通信系统matlab性能分析

目录 1.引言 2.算法仿真效果演示 3.数据集格式或算法参数简介 4.MATLAB核心程序 5.算法涉及理论知识概要 5.1 QPSK调制原理 5.2 空天地一体化网络信道模型 5.3 空天地一体化网络信道特性 6.参考文献 7.完整算法代码文件获得 1.引言 空天地一体化网络是一种将卫星通信…

【Delphi】接收windows文件夹中文件拖拽

本文根据EmailX45的视频文件&#xff0c;进行了优化改进&#xff0c;原文参见&#xff1a;Delphi: Drag and Drop Files from Explorer into TPanel / TMemo - YouTube 在Windows中&#xff0c;如果将选择的文件拖动到Delphi程序的控件上&#xff0c;有很多实现方法&#xff0c…

基于热力学熵增原理的EM-GAN

简介 简介:提出基于热力学熵增原理的EM-GAN,通过生成器熵最大化约束增强输出多样性。引入熵敏感激活函数与特征空间熵计算模块,在MNIST/CelebA等数据集上实现FID分数提升23.6%,有效缓解模式崩溃问题。 论文题目:Entropy-Maximized Generative Adversarial Network (EM-G…

HashMap与ConcurrentHashMap详解:实现原理、源码分析与最佳实践

引言 在Java编程中&#xff0c;集合框架是最常用的工具之一&#xff0c;而HashMap和ConcurrentHashMap则是其中使用频率最高的两个Map实现。它们都用于存储键值对数据&#xff0c;但在实现机制、性能特点和适用场景上有着显著差异。 HashMap作为单线程环境下的首选Map实现&am…

CSS之动画(奔跑的熊、两面反转盒子、3D导航栏、旋转木马)

一、 2D转换 1.1 transform: translate( ) 转换&#xff08;transform&#xff09; 是CSS3中具有颠覆性的特征之一&#xff0c;可以实现元素的位移、旋转、缩放等效果 移动&#xff1a;translate 旋转&#xff1a;rotate 缩放&#xff1a;scale 下图为2D转换的坐标系 回忆…

【笔记】在 MSYS2(MINGW64)中安装 python-maturin 的记录

#工作记录 &#x1f4cc; 安装背景 操作系统&#xff1a;MSYS2 MINGW64当前时间&#xff1a;2025年6月1日Python 版本&#xff1a;3.12&#xff08;通过 pacman 安装&#xff09;目标工具&#xff1a;maturin —— 用于构建和发布 Rust 编写的 Python 包 &#x1f6e0;️ 安装…

基于微信小程序的垃圾分类系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;没有什么华丽的语言&#xff0…

工作日记之权限校验-token的实战案例

背景说明 我们组负责维护的一个系统&#xff0c;前端界面挂载在其他两个系统上&#xff0c;因为历史遗留原因&#xff0c;同时也挂在公网上&#xff0c;没有登陆功能和用户体系&#xff0c;只要输入网址就能访问&#xff0c;虽然这个系统是给公司内部人员使用&#xff0c;但是…

mysql双主模式下基于keepalived的虚拟ip实现高可用模式搭建

数据库安装和升级和双主配置的操作可以参考我的另一篇文章&#xff1a; 数据库安装和升级和双主配置 1、在两台服务器都下载和安装keepalived 下载&#xff1a; yumdownloader --resolve keepalived 下载后得到&#xff1a; [rootlocalhost keepalivedRpm]# ll 总用量 1896 …

展会聚焦丨漫途科技亮相2025西北水务博览会!

2025第三届西北水务数字化发展论坛暨供排水节水灌溉新技术设备博览会在兰州甘肃国际会展中心圆满落幕。本届展会以“科技赋能水资源&#xff0c;数智引领新动能”为主题&#xff0c;活动汇集水务集团、科研院所、技术供应商等全产业链参与者&#xff0c;旨在通过前沿技术展示与…

单调栈(打卡)

本篇基于b站灵茶山艾府。 下面是灵神上课讲解的题目与课后作业&#xff0c;课后作业还有三道实在写不下去了&#xff0c;下次再写。 739. 每日温度 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是…

【机器学习基础】机器学习入门核心算法:层次聚类算法(AGNES算法和 DIANA算法)

机器学习入门核心算法&#xff1a;层次聚类算法&#xff08;AGNES算法和 DIANA算法&#xff09; 一、算法逻辑二、算法原理与数学推导1. 距离度量2. 簇间距离计算&#xff08;连接标准&#xff09;3. 算法伪代码&#xff08;凝聚式&#xff09; 三、模型评估1. 内部评估指标2. …

已有的前端项目打包到tauri运行(windows)

1.打包前端项目产生静态html、css、js 我们接下来用vue3 vite编写一个番茄钟案例来演示。 我们执行npm run build 命令产生的dist目录下的静态文件。 2.创建tarui项目 npm create tauri-applatest一路回车&#xff0c;直到出现。 3.启动运行 我们将打包产生的dist目录下的…

Unity3D仿星露谷物语开发55之保存地面属性到文件

1、目标 将游戏保存到文件&#xff0c;并从文件中加载游戏。 Player在游戏中种植的Crop&#xff0c;我们希望保存到文件中&#xff0c;当游戏重新加载时Crop的GridProperty数据仍然存在。这次主要实现保存地面属性&#xff08;GridProperties&#xff09;信息。 我们要做的是…

Java面试:企业协同SaaS中的技术挑战与解决方案

Java面试&#xff1a;企业协同SaaS中的技术挑战与解决方案 面试场景 在一家知名互联网大厂&#xff0c;面试官老王正在对一位应聘企业协同SaaS开发职位的程序员谢飞机进行技术面试。 第一轮提问&#xff1a;基础技术 老王&#xff1a;谢飞机&#xff0c;你好。首先&#xf…

SQL注入速查表(含不同数据库攻击方式与差异对比)

1. 字符串连接 字符串连接是SQL注入中常用的操作&#xff0c;用于将多个字符串拼接为一个&#xff0c;以构造复杂的注入语句。不同数据库的字符串连接语法存在显著差异&#xff0c;了解这些差异有助于精准构造payload。 Oracle&#xff1a;使用||操作符进行字符串连接&#xf…

uni-data-picker级联选择器、fastadmin后端api

记录一个部门及部门人员选择的功能&#xff0c;效果如下&#xff1a; 组件用到了uni-ui的级联选择uni-data-picker 开发文档&#xff1a;uni-app官网 组件要求的数据格式如下&#xff1a; 后端使用的是fastadmin&#xff0c;需要用到fastadmin自带的tree类生成部门树 &#x…

Mac电脑上本地安装 redis并配置开启自启完整流程

文章目录 一、安装 Redis方法 1&#xff1a;通过源码编译安装&#xff08;推荐&#xff09;方法 2&#xff1a;通过 Homebrew 安装&#xff08;可选&#xff09; 二、配置 Redis1. 创建配置文件和数据目录2. 修改配置文件 三、配置开机自启1、通过 launchd 系统服务&#xff08…