如何排查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
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/83404.shtml
英文地址,請注明出處:http://en.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…