Redis 熱 Key 問題的解決
在高并發(fā)的分布式系統(tǒng)中,Redis 作為高性能的內(nèi)存數(shù)據(jù)庫,廣泛用于緩存、會話存儲、計數(shù)器等場景。然而,隨著業(yè)務(wù)規(guī)模的增長,熱 Key(Hot Key)問題逐漸成為影響系統(tǒng)穩(wěn)定性和性能的重要隱患。
什么是熱 Key?
熱 Key 是指在 Redis 中被高頻訪問的某個 Key,其訪問頻率遠(yuǎn)超其他 Key,導(dǎo)致該 Key 所在的 Redis 實例或節(jié)點成為系統(tǒng)瓶頸。
典型特征:
- 單個 Key 的 QPS(每秒查詢數(shù))極高,可能達(dá)到數(shù)萬甚至更高。
- 該 Key 集中在一個 Redis 節(jié)點上,導(dǎo)致該節(jié)點 CPU、內(nèi)存、網(wǎng)絡(luò)帶寬負(fù)載過高。
- 其他 Key 的訪問正常,但該 Key 的訪問延遲明顯升高,甚至引發(fā)超時或服務(wù)不可用。
熱 Key 的常見場景
- 秒殺/搶購商品信息
- 某個熱門商品詳情被大量用戶頻繁查詢。
- 熱點新聞或文章
- 突發(fā)新聞的閱讀量、點贊數(shù)等 Key 被高頻訪問。
- 全局配置或公共數(shù)據(jù)
- 如系統(tǒng)開關(guān)、活動配置等,所有服務(wù)都依賴同一個 Key。
- 大 V 用戶數(shù)據(jù)
- 某個明星用戶的粉絲列表、動態(tài)被大量訪問。
- 緩存穿透/擊穿后的集中重建
- 大量請求同時重建同一個緩存 Key。
熱 Key 的危害
| 問題 | 影響 |
|---|---|
| 單點瓶頸 | 熱 Key 集中在一個 Redis 節(jié)點,導(dǎo)致該節(jié)點負(fù)載過高,影響其他 Key 的訪問。 |
| 網(wǎng)絡(luò)帶寬耗盡 | 高頻讀寫導(dǎo)致網(wǎng)絡(luò) IO 達(dá)到瓶頸,響應(yīng)變慢。 |
| CPU 過載 | Redis 單線程處理命令,熱 Key 導(dǎo)致主線程阻塞,影響其他請求。 |
| 緩存雪崩風(fēng)險 | 若熱 Key 失效,大量請求直接打到數(shù)據(jù)庫,可能壓垮 DB。 |
| 主從延遲 | 寫熱 Key 時,主節(jié)點壓力大,同步到從節(jié)點延遲增加。 |
如何發(fā)現(xiàn)熱 Key?
方法一:使用redis-cli --hotkeys(Redis 自帶工具)
這是最簡單直接的方式,適用于 Redis 4.0+ 版本。
原理
Redis 內(nèi)置了基于 LFU(Least Frequently Used)算法 的熱點 Key 發(fā)現(xiàn)機制。通過采樣命令訪問頻率,自動識別出訪問最頻繁的 Key。
使用方式
# 連接 Redis 并啟動熱 Key 檢測 redis-cli --hotkeys # 可指定 host 和 port redis-cli -h 127.0.0.1 -p 6379 --hotkeys
輸出示例
# Scanning the entire keyspace to find hot keys as well as
# average sizes per pattern of keys.
# 1 hottest key found at 'user:profile:10086' with 12532 hits
# 2 hottest key found at 'product:detail:hot' with 9823 hits
注意事項
- 需要開啟
maxmemory-policy為 LFU 相關(guān)策略(如allkeys-lfu或volatile-lfu),否則可能無效。 - 僅能發(fā)現(xiàn) 讀操作多的 Key,寫操作不會計入 LFU 計數(shù)。
方法二:SLOWLOG分析慢查詢
雖然不直接找“熱 Key”,但可以間接發(fā)現(xiàn)性能瓶頸。
命令
# 查看最近 10 條慢查詢 SLOWLOG GET 10 # 查看慢查詢總數(shù) SLOWLOG LEN # 重置慢日志 SLOWLOG RESET
輸出字段說明
id: 日志 IDtimestamp: 執(zhí)行時間戳duration: 執(zhí)行耗時(微秒)cmd: 完整命令(包含 Key 名)
如果某個 Key 多次出現(xiàn)在慢日志中,很可能是熱 Key 或大 Key。
配置慢查詢閾值
在 redis.conf 中設(shè)置:
slowlog-log-slower-than 10000 # 超過 10ms 的命令記錄 slowlog-max-len 1024 # 最多保存 1024 條日志
熱 Key 的解決方案
方案 1:本地緩存 + Redis(二級緩存)
思路:在應(yīng)用層使用本地緩存(如 Caffeine、Guava Cache)緩存熱 Key,減少對 Redis 的直接訪問。
// 示例:使用 Caffeine 緩存熱 Key
LoadingCache<String, String> cache = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(5, TimeUnit.MINUTES)
.build(key -> redis.get(key));
String value = cache.get("hot:product:123");優(yōu)點:簡單高效,顯著降低 Redis 壓力。
缺點:存在緩存不一致問題,需設(shè)置合理過期時間。
方案 2:Key 拆分(分片)
思路:將一個熱 Key 拆分為多個子 Key,分散訪問壓力。
# 原始熱 Key SET hot:product:123 "details" # 拆分為多個 Key SET hot:product:123:1 "details_part1" SET hot:product:123:2 "details_part2"
讀取時:隨機選擇一個子 Key 讀取,或合并多個。
適用場景:讀多寫少,且數(shù)據(jù)可拆分。
方案 3:讀寫分離 + 從庫擴(kuò)容
思路:將讀請求打到 Redis 從庫,寫請求打到主庫。
- 增加從節(jié)點數(shù)量,分擔(dān)讀壓力。
- 使用 Redis Cluster 或主從架構(gòu),合理分配讀請求。
注意:從庫有延遲,對一致性要求高的場景慎用。
方案 4:使用 Redis 集群(Cluster)
思路:通過 Redis Cluster 將 Key 分布到多個節(jié)點,避免單點過熱。
- Redis Cluster 使用 CRC16(key) % 16384 計算槽位,自動分片。
- 熱 Key 仍可能集中在某個槽位,但可通過 手動遷移槽位 分散。
建議:為特別熱的 Key 單獨部署一個 Redis 實例。
方案 5:異步更新 + 預(yù)加載
思路:避免大量請求同時觸發(fā)緩存重建。
- 使用 定時任務(wù) 預(yù)先加載熱 Key。
- 緩存失效前,異步刷新,避免集中重建。
// 使用 ScheduledExecutorService 定時刷新 scheduler.scheduleAtFixedRate(this::refreshHotKey, 0, 4, TimeUnit.MINUTES);
方案 6:限流與降級
思路:在應(yīng)用層對熱 Key 訪問進(jìn)行限流,防止系統(tǒng)崩潰。
- 使用 Sentinel、Hystrix 等熔斷限流框架。
- 當(dāng)訪問超過閾值時,返回默認(rèn)值或降級數(shù)據(jù)。
@SentinelResource(value = "getHotKey", blockHandler = "handleHotKey")
public String getHotKey() {
return redis.get("hot:key");
}
public String handleHotKey(BlockException ex) {
return "default_value";到此這篇關(guān)于Redis 熱 Key 問題的解決的文章就介紹到這了,更多相關(guān)Redis 熱 Key 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis結(jié)合Caffeine兩級緩存的三種實現(xiàn)方式
本文主要介紹了Redis結(jié)合Caffeine兩級緩存的實現(xiàn)示例,通過手動、Spring注解及自定義切面三種方式實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2025-08-08
Redis和數(shù)據(jù)庫雙寫一致性問題的解決方案
文章探討了Redis與數(shù)據(jù)庫雙寫一致性問題,提出四種解決方案:先更新數(shù)據(jù)庫再刪除緩存(推薦),延時雙刪避免并發(fā)不一致,監(jiān)聽數(shù)據(jù)庫變更實現(xiàn)最終一致性,加分布式鎖保障強一致,核心原則是優(yōu)先保證數(shù)據(jù)庫正確性,緩存操作可失敗重試,強一致性需犧牲性能2025-08-08
Redis實現(xiàn)分布式Session管理的機制詳解
這篇文章主要介紹了Redis實現(xiàn)分布式Session管理的機制詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01
Redis高效查詢大數(shù)據(jù)的實踐與優(yōu)化詳細(xì)指南
Redis 是一種高性能的鍵值存儲數(shù)據(jù)庫,廣泛應(yīng)用于緩存,排行榜,計數(shù)器等場景,本文將圍繞如何高效查詢Redis中滿足條件的數(shù)據(jù)展開討論,感興趣的小伙伴可以了解下2025-04-04
解析Redis 數(shù)據(jù)結(jié)構(gòu)之簡單動態(tài)字符串sds
Redis 的 string 類型為何使用sds而不是 C 字符串,本文主要介紹 string 的數(shù)據(jù)結(jié)構(gòu)—— 簡單動態(tài)字符串(Simple Dynamic String) 簡稱sds的相關(guān)知識,需要的朋友可以參考下2021-11-11
Centos7.3安裝Redis4.0.6詳細(xì)圖文教程
這篇文章主要介紹了Centos7.3安裝Redis4.0.6詳細(xì)教程圖解,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2018-10-10

