Redis 內存管理
1. Redis 給緩存數據設置過期時間的作用
給緩存數據設置過期時間(TTL, Time-To-Live)有以下幾個重要作用:
(1) 自動釋放內存
- 避免緩存數據無限增長,導致 Redis 內存溢出。
- 例如,在 會話管理、短連接信息、臨時令牌 等場景下,設置過期時間可以自動清理數據,避免占用大量內存。
(2) 提高緩存的實時性
- 設置較短的 TTL 讓數據 保持新鮮,保證用戶獲取的是最新的數據。
- 例如,熱點新聞、秒殺活動商品庫存,需要定期更新。
(3) 限制數據的生命周期
- 適用于 驗證碼、用戶 Token 等數據,超時后自動失效,提高安全性。
- 例如,驗證碼有效期 5 分鐘,超時后自動刪除,防止惡意重復使用。
(4) 提高緩存命中率
- 如果數據頻繁變化,不設置過期時間,可能導致大量 冷數據 長期占用內存,影響緩存命中率。
- 通過 TTL 控制數據生命周期,保證 Redis 主要存儲熱點數據。
2. Redis 是如何判斷數據是否過期的?
Redis 通過 兩種方式 判斷數據是否過期:
(1) 訪問 Key 時檢查(惰性刪除)
- **機制:**當客戶端訪問一個 Key(如 GET key)時,Redis 檢查其過期時間:
- 如果 Key 已過期,立即刪除,并返回
nil
或默認值。 - 如果 Key 未過期,則正常返回數據。
- 如果 Key 已過期,立即刪除,并返回
- 優點:減少 CPU 資源占用,僅對訪問的數據進行檢查。
- 缺點:如果一個 Key 長期不被訪問,即使已經過期,也不會被刪除,可能導致 內存占用過高。
(2) 定期掃描過期 Key(定期刪除)
- **機制:**Redis 每 100ms 進行一次過期檢查:
- 隨機抽取部分 Key(默認 20 個)。
- 檢查是否過期,如果過期就刪除。
- 如果刪除的 Key 超過 25%(默認閾值),則繼續下一輪檢查,避免過期 Key 堆積。
- 優點:可以主動清理一部分過期數據,減少內存占用。
- 缺點:無法保證所有過期 Key 及時刪除,仍可能導致部分過期數據滯留。
3. Redis 過期 Key 的刪除策略
Redis 采用 三種刪除策略 結合使用,以平衡 性能 和 內存占用。
刪除策略 | 觸發時機 | 優點 | 缺點 |
---|---|---|---|
惰性刪除 | 訪問 Key 時檢查 | CPU 資源占用低,只檢查訪問的數據 | 冷數據不會被清理,可能導致內存占滿 |
定期刪除 | 每 100ms 掃描部分 Key | 主動清理一部分過期 Key,避免過期數據堆積 | 無法清理所有過期 Key,仍可能占用大量內存 |
內存淘汰(Eviction) | 內存滿時觸發 | 確保 Redis 可用,釋放空間給新數據 | 可能刪除熱點數據,影響緩存命中率 |
4. Redis 的內存淘汰策略(Eviction Policy)
如果過期 Key 沒有及時刪除,導致 內存達到 maxmemory 限制,Redis 會采用 內存淘汰策略 釋放空間,主要有三類:
(1) 直接拒絕寫入
noeviction
(默認策略):- 機制:當 Redis 內存滿了,拒絕新的寫入請求,返回錯誤。
- 適用場景:適用于 不能丟失數據 的場景(如金融交易數據)。
- 缺點:可能導致系統不可用。
(2) 僅淘汰帶過期時間(TTL)的 Key
volatile-lru
:淘汰 帶 TTL 的 Key,按 LRU(最近最少使用)刪除。volatile-lfu
:淘汰 帶 TTL 的 Key,按 LFU(最少使用)刪除。volatile-random
:隨機刪除 帶 TTL 的 Key。volatile-ttl
:優先刪除 TTL 最短的 Key。
(3) 淘汰所有 Key
allkeys-lru
:在 所有 Key 中,刪除 最近最少使用(LRU) 的 Key。allkeys-lfu
:在 所有 Key 中,刪除 最少使用(LFU) 的 Key。allkeys-random
:隨機刪除 任意 Key。
淘汰策略對比
策略 | 適用范圍 | 適用場景 | 優點 | 缺點 |
---|---|---|---|---|
noeviction | 所有 Key | 不能丟失數據的業務 | 數據絕對安全 | 可能導致 Redis 無法寫入 |
allkeys-lru | 所有 Key | 普通緩存(如 Web 緩存) | 保留熱點數據 | LRU 計算有額外開銷 |
volatile-lru | 僅帶 TTL | 有過期時間的緩存 | 保留熱點緩存數據 | TTL 過少時,可能無 Key 可刪除 |
allkeys-random | 所有 Key | 低優先級緩存 | 簡單高效 | 可能誤刪熱點數據 |
volatile-random | 僅帶 TTL | 無訪問規律的緩存 | 低計算成本 | 命中率低 |
volatile-ttl | 僅帶 TTL | 定期緩存數據 | 優先刪除即將過期的數據 | TTL 設定不合理可能影響命中率 |
allkeys-lfu | 所有 Key | 熱點數據變化快 | 優先保留高頻訪問數據 | 計算比 LRU 高 |
volatile-lfu | 僅帶 TTL | 高頻訪問緩存 | 結合訪問頻率和 TTL 進行優化 | 計算比 LRU 高 |
5. 綜述
- 為什么 Redis 需要設置過期時間?
- 釋放內存,防止數據無限增長。
- 保證數據實時性,避免使用陳舊數據。
- 提高緩存命中率,讓 Redis 保留熱點數據。
- 符合業務需求(如驗證碼、Token 需要自動失效)。
- Redis 如何判斷 Key 是否過期?
- 惰性刪除:訪問 Key 時檢查,若過期則刪除。
- 定期刪除:每 100ms 隨機檢查部分 Key,并刪除過期 Key。
- Redis 過期 Key 如何刪除?
- 惰性刪除 + 定期刪除 + 內存淘汰策略 結合,平衡 性能 和 內存占用。
- Redis 如何在內存滿時清理數據?
- 默認拒絕寫入(
noeviction
) - 基于 LRU/LFU/TTL 的內存淘汰策略
- 隨機淘汰或基于訪問頻率、TTL 進行優化
- 默認拒絕寫入(
通過合理設置 過期時間 + 淘汰策略,可以讓 Redis 高效管理內存,保證緩存數據的 可用性和實時性。