Redis 的過期策略和淘汰策略是內存管理的核心機制,分別用于處理鍵的自動失效和內存不足時的數據清理。以下是詳細說明:
1 、過期刪除策略(Expiration Policy)
處理已設置過期時間(EXPIRE
)的鍵,確保它們在過期后被刪除。
1.1 被動刪除(惰性刪除)
- 默認行為:始終啟用,無需配置。
- 觸發時機:當客戶端嘗試訪問某個鍵時,Redis 會檢查其是否過期。
- 行為:若鍵已過期,則直接刪除并返回空結果,不返回數據。
- 優點:僅在訪問時檢查,節省 CPU 資源。
- 缺點:長期未被訪問的過期鍵可能殘留內存(需配合定期刪除)。
1.2 定期刪除(主動掃描)
- 默認行為:始終啟用,無需配置。
- 觸發時機:Redis 默認每秒 10 次隨機抽查部分鍵。
- 行為:
- 隨機抽取 20 個設置了過期時間的鍵。
- 刪除其中已過期的鍵。
- 若本輪刪除的鍵超過 25%,重復流程(避免阻塞)。
- 配置參數:
hz 10
:控制定期刪除的頻率(默認每秒 10 次)。active-expire-effort
:調整掃描強度(1-10,值越大越嚴格)。
- 優點:平衡內存和性能,避免內存泄漏。
- 缺點:無法保證及時刪除所有過期鍵。
1.3. 過期鍵的存儲
- Redis 使用獨立的字典(
expires
)記錄鍵的過期時間,與主鍵字典分離。 - 刪除過期鍵時,會同時從主字典和
expires
字典中移除。
2 淘汰刪除策略(Eviction Policy)
當內存達到 maxmemory
限制時,根據策略主動刪除鍵以釋放空間。
2.1 不淘汰(noeviction)
- 行為:內存不足時,拒絕寫入操作(返回錯誤),但允許讀取和刪除。
- 適用場景:數據重要性高,不允許丟失(如分布式鎖)。
2.2 LRU 策略(Least Recently Used)
- allkeys-lru:從所有鍵中淘汰最久未使用的鍵。
- volatile-lru:僅從設置了過期時間的鍵中淘汰最久未使用的鍵。
- 實現:Redis 使用近似 LRU 算法,維護一個隨機采樣的候選池(默認 5 個樣本,可通過
maxmemory-samples
調整)。
2.3 LFU 策略(Least Frequently Used,Redis 4.0+)
- allkeys-lfu:從所有鍵中淘汰訪問頻率最低的鍵。
- volatile-lfu:僅從設置了過期時間的鍵中淘汰訪問頻率最低的鍵。
- 實現:記錄鍵的訪問次數和衰減因子,優先淘汰冷數據。
2.4 隨機策略
- allkeys-random:從所有鍵中隨機淘汰。
- volatile-random:僅從設置了過期時間的鍵中隨機淘汰。
- 適用場景:數據無明顯訪問模式,需快速釋放內存。
2.5 TTL 策略
- volatile-ttl:僅淘汰設置了過期時間的鍵中,剩余生存時間(TTL)最短的鍵。
- 適用場景:希望優先保留長期有效的數據。
2.6 策略對比與選擇建議
策略 | 適用場景 | 特點 |
---|---|---|
noeviction | 禁止數據丟失(如緩存+數據庫模式) | 內存不足時阻塞寫入 |
allkeys-lru | 緩存場景,數據訪問模式符合局部性 | 高效利用內存,推薦默認策略 |
volatile-lru | 需結合過期時間使用 | 僅淘汰帶過期時間的鍵 |
allkeys-lfu | 訪問頻率差異大的數據 | 適合熱點數據頻繁訪問的場景 |
volatile-ttl | 希望短期數據優先淘汰 | 簡單直接,但可能誤刪熱點數據 |
2.7 最佳實踐
- 緩存場景:
- 優先使用
allkeys-lru
或allkeys-lfu
,結合maxmemory-policy
配置。 - 設置合理的
maxmemory
(如系統內存的 60%-80%)。
- 優先使用
- 持久化數據:
- 使用
noeviction
,配合數據庫做主從備份。
- 使用
- 混合場景:
- 結合
volatile-ttl
或volatile-lru
,為部分鍵設置過期時間。
- 結合
2.8 淘汰策略的其它問題
2.8.1 數據庫有1000萬數據,Redis只能緩存20w數據,如何保證Redis中的數據都是熱點數據 ?
使用allkeys-lru(挑選最近最少使用的數據淘汰)淘汰策略,留下來的都是經常訪問的熱點數據
2.8.2 Redis的內存用完了會發生什么?
主要看數據淘汰策略是什么?如果是默認的配置( noeviction ),會直接報錯