緩存有效期與淘汰政策
有效期 TTL (Time to live)
設定有效期的作用:
- 節省空間
- 做到資料弱一緻性,有效期失效後,可以保證資料的一緻性
Redis的過期政策
過期政策通常有以下三種:
-
定時過期
每個設定過期時間的key都需要建立一個定時器,到過期時間就會立即清除。該政策可以立即清除過期的資料,對記憶體很友好;但是會占用大量的CPU資源去處理過期的資料,進而影響緩存的響應時間和吞吐量。
setex('a', 300, 'aval') setex('b', 600, 'bval')
-
惰性過期
隻有當通路一個key時,才會判斷該key是否已過期,過期則清除。該政策可以最大化地節省CPU資源,卻對記憶體非常不友好。極端情況可能出現大量的過期key沒有再次被通路,進而不會被清除,占用大量記憶體。
-
定期過期
每隔一定的時間,會掃描一定數量的資料庫的expires字典中一定數量的key,并清除其中已過期的key。該政策是前兩者的一個折中方案。通過調整定時掃描的時間間隔和每次掃描的限定耗時,可以在不同情況下使得CPU和記憶體資源達到最優的平衡效果。
expires字典會儲存所有設定了過期時間的key的過期時間資料,其中,key是指向鍵空間中的某個鍵的指針,value是該鍵的毫秒精度的UNIX時間戳表示的過期時間。鍵空間是指該Redis叢集中儲存的所有鍵。
Redis中同時使用了惰性過期和定期過期兩種過期政策。
Redis過期删除采用的是定期删除,預設是每100ms檢測一次,遇到過期的key則進行删除,這裡的檢測并不是順序檢測,而是随機檢測。那這樣會不會有漏網之魚?顯然Redis也考慮到了這一點,當我們去讀/寫一個已經過期的key時,會觸發Redis的惰性删除政策,直接回幹掉過期的key
為什麼不用定時删除政策?
定時删除,用一個定時器來負責監視key,過期則自動删除。雖然記憶體及時釋放,但是十分消耗CPU資源。在大并發請求下,CPU要将時間應用在處理請求,而不是删除key,是以沒有采用這一政策.
定期删除+惰性删除是如何工作的呢?
定期删除,redis預設每個100ms檢查,是否有過期的key,有過期key則删除。需要說明的是,redis不是每個100ms将所有的key檢查一次,而是随機抽取進行檢查(如果每隔100ms,全部key進行檢查,redis豈不是卡死)。是以,如果隻采用定期删除政策,會導緻很多key到時間沒有删除。
于是,惰性删除派上用場。也就是說在你擷取某個key的時候,redis會檢查一下,這個key如果設定了過期時間那麼是否過期了?如果過期了此時就會删除。
采用定期删除+惰性删除就沒其他問題了麼?
不是的,如果定期删除沒删除key。然後你也沒即時去請求key,也就是說惰性删除也沒生效。這樣,redis的記憶體會越來越高。那麼就應該采用記憶體淘汰機制。
緩存淘汰 eviction
Redis自身實作了緩存淘汰
Redis的記憶體淘汰政策是指在Redis的用于緩存的記憶體不足時,怎麼處理需要新寫入且需要申請額外空間的資料。
- noeviction:當記憶體不足以容納新寫入資料時,新寫入操作會報錯。
- allkeys-lru:當記憶體不足以容納新寫入資料時,在鍵空間中,移除最近最少使用的key。
- allkeys-random:當記憶體不足以容納新寫入資料時,在鍵空間中,随機移除某個key。
- volatile-lru:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,移除最近最少使用的key。
- volatile-random:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,随機移除某個key。
- volatile-ttl:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,有更早過期時間的key優先移除。
redis 4.x 後支援LFU政策,最少頻率使用
- allkeys-lfu
- volatile-lfu
LRU
LRU(Least recently used,最近最少使用)
LRU算法根據資料的曆史通路記錄來進行淘汰資料,其核心思想是“如果資料最近被通路過,那麼将來被通路的幾率也更高”。
基本思路
- 新資料插入到清單頭部;
- 每當緩存命中(即緩存資料被通路),則将資料移到清單頭部;
- 當清單滿的時候,将清單尾部的資料丢棄。
LFU
LFU(Least Frequently Used 最近最少使用算法)
它是基于“如果一個資料在最近一段時間内使用次數很少,那麼在将來一段時間内被使用的可能性也很小”的思路。

LFU需要定期衰減。不然有一些資料會倚老賣老
Redis淘汰政策的配置
- maxmemory 最大使用記憶體數量
- maxmemory-policy noeviction 淘汰政策
多思考也是一種努力,做出正确的分析和選擇,因為我們的時間和精力都有限,是以把時間花在更有價值的地方。