目錄
前言
1.過期策略
1.1過期策略——DB結構
1.2過期策略——惰性刪除
1.3過期策略——定期刪除
2.淘汰策略
2.1最少最近使用和使用頻率原理
2.2內存淘汰策略執行流程
總結:
前言
Redis之所以性能強,主要的原因就是基于內存存儲。然而單節點的Redis其內存大小不宜過大,會影響持久化或主從同步性能。
我們可以通過修改配置文件來設置Redis的最大內存:
當內存使用達到上限時,就無法存儲更多數據了,再添加數據時就會淘汰其他數據。所有就有內存淘汰策略。
?
1.過期策略
對于Redis緩存,我們可以通過expire命令給Redis的key設置TTL(存活時間):
可以發現,當key的TTL到期以后,再次訪問name返回時nil,說明這個key已經不存在了,對應的內存也得到釋放。從而起到內存回收的目的。
1.1過期策略——DB結構
redis本身是一個典型的key-value內存存儲數據庫,因此所有的key,value都保存在之前學習過的Dict結構中。不過在
其database結構體中,有兩個Dict:一個用來記錄key-value;另一個用來記錄key-TTL。
內存結構圖:
所以Redis利用兩個Dict分別記錄key-value對及key-TTL對
?
1.2過期策略——惰性刪除
是不是TTL到期就立即刪除了呢?
如果key很多,都給這些key設置定時器,對于CPU會有非常的壓力,這樣就會嚴重影響Redis服務本身的一個性能。
所以實際應用種Redis不是采用立即刪除,而是周期刪除,惰性刪除這兩種策略。
惰性刪除:顧名思義并不是在TTL到期后就立刻刪除,而是在訪問一個key的時候,檢查該key的存活時間,如果已經過期才執行刪除。
惰性刪除是我去訪問它才會被刪除,如果很長一段時間都沒有被訪問,就永遠不會被刪除,所以就需要周期刪除。
?
1.3過期策略——定期刪除
周期刪除:顧明思議是通過一個定時任務,周期性的抽樣部分過期的key,然后執行刪除。執行周期有兩種:
- Redis會設置一個定時任務servercron(),按照server.hz的頻率來執行過期key清理,模式為SLOW
- Redis的每個事件循環前會調用beforesleep()函數,執行過期key清理,模式為FAST
SLOW模式規則(低頻-高時長):
- 執行頻率受server.hz影響,默認為10,即每秒執行10次,每個執行周期100ms.
- 執行清理耗時不超過一次執行周期的25%.
- 逐個遍歷db,逐個遍歷db中的bucket,抽取20個key判斷是否過期
- 如果沒達到時間上限(25ms)并且過期key比例大于10%,再進行一次抽樣,否則結束
FAST模式規則(過期key比例小于10%不執行):
- 執行頻率受beforesleep()調用頻率影響,但兩次fast模式間隔不低于2ms
- 執行清理耗時不超過1ms
- 逐個遍歷db,逐個遍歷db中的bucket,抽取20個key判斷是否過期
- 如果 如果沒達到時間上限(1ms)并且過期key比例大于10%,再進行一次抽樣,否則結束
?
2.淘汰策略
內存淘汰:就是當Redis內存使用達到設置的閾值時,Redis主動挑選部分key刪除以釋放更多內存的流程。
Redis會在處理客戶端命令的方法processCommand()中嘗試做內存淘汰:
Redis支持8種不同策略來選擇要刪除的key:
四種算法-八種策略
?
2.1最少最近使用和使用頻率原理
比較容易混淆的有兩個:
關于key的最少最近使用和使用頻率如何實現?
Redis的數據都會被封裝為RedisObject結構:
LFU的訪問系數之所以叫邏輯訪問次數,是因為并不是每次key都被訪問都計數,而是通過運算:
?
2.2內存淘汰策略執行流程
關于淘汰策略執行流程圖:
?
總結:
為了防止內存的達到上限,redis對內存的管理策略一般分為兩類:?
1.內存過期策略: 對過期的key的回收策略
- ?惰性刪除(單個)
- ?過期刪除(批量)
設置一個定時任務,周期性的進行采樣抽取,并刪除過期的key.
- SLOW模式: 低頻 高時長
?- FAST模式: ? 高頻 低時長
2.內存淘汰策略: 內存使用達到上限的回收策略
?? ??八種策略,四種算法
- ??LRU ?? ?Least Recently Used ?回收[最少最近使用 ?當前時間-上一次使用時間]?
- ? LFU?? ?Least FrequentLy Used ?回收[使用頻率最少的key ?使用頻率最少的]
- ?隨機 ?
- ?TTL