一篇帶你了解Redis刪除策略
Redis刪除策略

過期數據在Redis中所有設置了TTL的數據可能不會立即刪除,Redis會將該鍵帶上過期時間存放到內存中的一個Expires字典中。
當執行TTL命令后會返回其狀態
- redis 127.0.0.1:6379> TTL key
- -2: Key已經過期、被刪除、未定義
- -1: 永久有效
- XX: XX為 key 的剩余生存時間,以秒為單位
這里的已過期數據,真的刪除了嗎?
數據刪除策略
前面說到當存儲一個key之后,這個key連同有效期被存儲到Expires字典中,具體什么時候刪除的呢?
通常刪除某個key,我們有如下三種處理方式:
- 定時刪除
- 惰性刪除
- 定期刪除
1. 定時刪除
創建一個定時器,當key設置有過期時間,且過期時間到達時,由定時器任務立即執行對鍵的刪除操作
優點:節省內存,到時就刪除,快速釋放掉不必要的內存空間
缺點:CPU壓力大,無論此時CPU過載有多高,都會占用CPU,會影響Redis服務器的響應時間和吞吐量
總結:用處理器性能換取內存空間(時間換空間)
2. 惰性刪除
數據到達過期時間后,不做處理。等下次訪問時,
- 如果未過期,返回數據
- 如果已過期,刪除并返回不存在
優點:節約CPU性能,發現必須刪除時才刪除
缺點:內存壓力大,出現長期占用內存空間的數據
總結:用內存空間換取CPU處理性能(空間換時間)
3. 定期刪除
定時刪除和惰性刪除都太極端了,定期刪除就是一個比較好的折中方案
周期性的輪詢Redis庫中的時效性數據,采用隨機抽取的策略,利用過期數據占比的方式控制刪除頻度
特點:
- CPU占用設置有峰值,檢測頻度可以自定義
- 內存壓力不是很大,長期占用內存的冷數據會被持續清理
總結:周期性抽查存儲空間(隨機抽查,重點抽查)
定期刪除,Redis服務器啟動初始化時,讀取配置server.hz的值,默認為10
每秒執行server.hz次serverCorn()->databaseCorn()->activeExpireCycle()
其中activeExpireCycle()對每個Expires[*]逐一檢測,每次執行時間為250ms/server.hz
對某個Expires[*]檢測時,隨機挑選幾個key檢測:
- 如果key超時,刪除key
- 如果一輪中刪除key的數量>W*25%,循環該過程(重點抽查)
- 如果一輪中刪除key的數量
- 其中W取值=ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP的屬性值
4. 刪除策略對比
逐出算法
1. 新數據進入檢測
當新數據進入Redis時,內存不足怎么辦?
Redis使用內存存儲數據,在執行每一個命令前,會調用freeMermoryIfNeeded()檢測內存是否充足。如果內存不滿足新加入的數據的最低存儲要求,Redis要臨時刪除一些數據為當前指令清理存儲空間。清理數據的策略成為逐出算法(內存淘汰策略)
注意:逐出數據的過程不是100%能夠清理出足夠的可使用的內存空間,如果不成功會反復執行。當前所有數據嘗試執行完畢后,如果不能達到內存清理的要求,將出現錯誤信息。
- (error) OOM command not allowed when used memory >'maxmemory'
2. 逐出算法配置
- 最大可用內存
- maxmermory
- 說明:占用物理內存的比例。默認值是0,標識不限制。生產上根據需要設置,一般在50%以上
- 每次選取待刪除的個數
- maxmermroy-samples
- 說明:選取待刪除的數據時,如果掃描全庫,會嚴重消耗性能,降低讀寫性能。因為采用隨機獲取數據的方式作為待檢測刪除數據
- 刪除策略
- maxmermory-policy
- 說明:達到最大內存后,對被挑選出來的數據進行刪除的策略
3. 逐出算法
如果Redis配置了maxmemory和maxmemory-policy策略,則當Redis內存數據達到maxmemory時,會根據maxmemory-policy配置來淘汰內存數據,以避免OOM。
根據maxmemory-policy的配置項,執行刪除策略時分為兩大類:易失數據(設置過期時間的數據)、永久數據。Redis默認值為volatile-lru.
檢測易失數據(會過期的數據集server.db[i].expries)
- volatile-lru:挑選最近最少使用的數據淘汰
- volatile-lfu:挑選最近使用次數最少的數據淘汰
- volatile-random:任意選擇數據淘汰
- volatile-ttl:挑選即將過期的數據淘汰
檢測全庫數據(所有數據集server.db[i].dict)
- allkeys-lru:挑選最近最少使用的數據淘汰
- allkeys-lfu:挑選最近使用次數最少的數據淘汰
- allkeys-random:任意選擇數據淘汰
放棄數據淘汰
- no-enviction:禁止數據淘汰,會引發OOM(Out Of Memroy)。Redis4.0默認策略
LRU和LFU算法示例
4. 數據逐出策略配置依據
使用info命令數據監控信息,查詢緩存hit和miss次數,根據業務需要配置逐出算法。
本文轉載自微信公眾號「Java養基場」,可以通過以下二維碼關注。轉載本文請聯系Java養基場公眾號。