博客 / 詳情

返回

Redis 熱點 key 治理

Redis 的“熱點 key”問題指的是某些 key 被頻繁訪問(讀或寫),導致服務器負載不均衡甚至性能瓶頸。在高併發系統中,這是常見的性能隱患之一。


一、熱點 Key 的危害

  • 單點瓶頸:某個 key 被高頻訪問,導致 Redis CPU 飆升,QPS 降低。
  • 緩存擊穿:熱點 key 失效後瞬間大量請求落到數據庫,可能造成雪崩。
  • 負載不均:集羣中某節點因為熱點 key 負載過高。
  • 延遲上升:影響整體服務響應時間,拖慢其他正常請求。

二、熱點 Key 的識別方法

1. 使用 Redis 命令定位熱點 Key:

  • MONITOR(開發/測試環境用):實時查看請求命令
  • redis-cli --hotkeys:採樣找出熱點 key(Redis 4.0+)
  • slowlog get:分析慢查詢的 key
  • info commandstats:查看命令訪問頻率
  • Redis 集羣環境可結合 proxy(如 Twemproxy)或分析訪問日誌

三、熱點 Key 的治理策略

1. 緩存預熱(預加載)

熱點 key 在高峯期前主動設置好緩存,避免冷啓動時併發打穿數據庫。

# 啓動前或定時腳本預熱
SET user:10086 {...} EX 3600

2. 使用多級緩存(本地 + Redis)

減少熱點 key 對 Redis 的壓力,典型方案:

  • 本地緩存(如 Guava、Caffeine、LruCache)
  • 分佈式緩存(Redis)
// 示例偽代碼
if (localCache.contains(key)) return localCache.get(key);
val = redis.get(key);
localCache.put(key, val);

3. 熱點 Key 拆分(哈希打散)

將一個 key 拆成多個 key,降低單點訪問壓力。

  • 例:將 hotkey 拆為 hotkey_1\~hotkey_10,客户端隨機訪問或輪詢
SET hotkey_1 "val"
SET hotkey_2 "val"
...
GET hotkey_${random(1,10)}

4. 異步更新 + 延遲雙刪

保證熱點 key 一致性但減小 Redis 壓力:

更新 DB 後:
1. 刪除 Redis key
2. 異步通知更新業務邏輯
3. 延遲再次刪除 key(避免併發寫入後被舊數據覆蓋)

5. 加鎖防擊穿

針對失效的熱點 key,可使用互斥鎖(如 Redis 的分佈式鎖)防止併發回源:

-- 獲取鎖
SETNX lock:key true
-- 設置過期
EXPIRE lock:key 3
-- 查詢 DB & set 緩存
-- 刪除鎖
DEL lock:key

可使用 Redisson、ZooKeeper 等實現分佈式鎖。


6. 合理設置過期時間(TTL)

防止多個熱點 key 同時過期,觸發併發回源:

  • 使用隨機 TTL 避免“緩存雪崩”
expire = 3600 + random.randint(0, 300)
redis.set('key', val, ex=expire)

7. 請求限流

對訪問頻率過高的 key 設置限流策略,保護後端服務:

  • 應用層限流(如 Guava RateLimiter)
  • Redis 令牌桶 / 計數器實現限流

8. 數據分片 / 分佈式部署

  • 將 Redis 集羣分區部署,熱點數據分佈到不同實例
  • 使用 proxy 分流請求(如 Codis、Twemproxy)

四、治理最佳實踐總結

手段 應用場景 優勢 注意事項
本地緩存 熱點讀 減輕 Redis 壓力 一致性問題
Key 拆分 熱點 key 寫多 分攤負載 編碼複雜度
緩存預熱 高併發初期 避免擊穿 需計劃
分佈式鎖 緩存失效 防擊穿 增加延遲
延遲雙刪 DB寫操作 保證一致性 需時機把握好

user avatar andy-croxall 頭像 wenhuaxian 頭像 h57 頭像 xiongmaoxianshi 頭像 mashubumaopao 頭像 bigxia 頭像
6 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.