Redis 如何處理過期數(shù)據(jù)的
對于已經(jīng)過期的數(shù)據(jù)磁餐,Redis 將使用兩種策略來刪除這些過期鍵按咒,它們分別是惰性刪除和定期刪除瞳筏。
惰性刪除
惰性刪除是指 Redis 服務(wù)器不主動刪除過期的鍵值妻献,而是當(dāng)訪問鍵值時,再檢查當(dāng)前的鍵值是否過期抓半,如果過期則執(zhí)行刪除并返回 null 給客戶端;如果沒過期則正常返回值信息給客戶端格嘁。
它的優(yōu)點是不會浪費太多的系統(tǒng)資源笛求,只是在每次訪問時才檢查鍵值是否過期。缺點是刪除過期鍵不及時糕簿,造成了一定的空間浪費探入。
定期刪除
定期刪除是指 Redis 服務(wù)器每隔一段時間會檢查一下數(shù)據(jù)庫,看看是否有過期鍵可以被清除懂诗。
默認(rèn)情況下 Redis 定期檢查的頻率是每秒掃描 10 次蜂嗽,用于定期清除過期鍵。當(dāng)然此值還可以通過配置文件進(jìn)行設(shè)置殃恒,在 redis.conf 中修改配置“hz”即可植旧,默認(rèn)的值為“hz 10”。
定期刪除的掃描并不是遍歷所有的鍵值對芋类,這樣的話比較費時且太消耗系統(tǒng)資源隆嗅。Redis 服務(wù)器采用的是隨機抽取形式,每次從過期字典中侯繁,取出 20 個鍵進(jìn)行過期檢測胖喳,過期字典中存儲的是所有設(shè)置了過期時間的鍵值對。如果這批隨機檢查的數(shù)據(jù)中有 25% 的比例過期贮竟,那么會再抽取 20 個隨機鍵值進(jìn)行檢測和刪除丽焊,并且會循環(huán)執(zhí)行這個流程,直到抽取的這批數(shù)據(jù)中過期鍵值小于 25%咕别,此次檢測才算完成技健。
Redis 內(nèi)存淘汰策略
內(nèi)存淘汰算法主要包含兩種:LRU 淘汰算法和 LFU 淘汰算法。
LRU( Least Recently Used惰拱,最近最少使用)淘汰算法:是一種常用的頁面置換算法雌贱,也就是說最久沒有使用的緩存將會被淘汰。
LRU 是基于鏈表結(jié)構(gòu)實現(xiàn)的偿短,鏈表中的元素按照操作順序從前往后排列欣孤,最新操作的鍵會被移動到表頭,當(dāng)需要進(jìn)行內(nèi)存淘汰時昔逗,只需要刪除鏈表尾部的元素即可降传。
LFU(Least Frequently Used,最不常用的)淘汰算法:最不常用的算法是根據(jù)總訪問次數(shù)來淘汰數(shù)據(jù)的勾怒,它的核心思想是“如果數(shù)據(jù)過去被訪問多次婆排,那么將來被訪問的頻率也更高”声旺。
LFU 相對來說比 LRU 更“智能”,因為它解決了使用頻率很低的緩存段只,只是最近被訪問了一次就不會被刪除的問題腮猖。如果是使用 LRU 類似這種情況數(shù)據(jù)是不會被刪除的,而使用 LFU 的話翼悴,這個數(shù)據(jù)就會被刪除缚够。
內(nèi)存淘汰和過期策略是完全不同的兩個概念,內(nèi)存淘汰策略是當(dāng)內(nèi)存不夠用時才會觸發(fā)的一種機制鹦赎,它在 Redis 4.0 之后提供了 8 種內(nèi)存淘汰策略谍椅,這些淘汰策略主要使用了近 LRU 淘汰算法和 LFU 淘汰算法。
LRU( Least Recently Used古话,最近最少使用)淘汰算法:是一種常用的頁面置換算法雏吭,也就是說最久沒有使用的緩存將會被淘汰。
noeviction:不淘汰任何數(shù)據(jù)陪踩,當(dāng)內(nèi)存不足時杖们,執(zhí)行緩存新增操作會報錯,它是 Redis 默認(rèn)內(nèi)存淘汰策略肩狂。
allkeys-lru:淘汰整個鍵值中最久未使用的鍵值摘完。
allkeys-random:隨機淘汰任意鍵值。
volatile-lru:淘汰所有設(shè)置了過期時間的鍵值中最久未使用的鍵值傻谁。
volatile-random:隨機淘汰設(shè)置了過期時間的任意鍵值孝治。
volatile-ttl:優(yōu)先淘汰更早過期的鍵值。
volatile-lfu审磁,淘汰所有設(shè)置了過期時間的鍵值中最少使用的鍵值谈飒。
allkeys-lfu,淘汰整個鍵值中最少使用的鍵值态蒂。
可以使用 config get maxmemory-policy 命令杭措,來查看當(dāng)前 Redis 的內(nèi)存淘汰策略
內(nèi)存淘汰策略可以通過配置文件來修改,redis.conf 對應(yīng)的配置項是“maxmemory-policy noeviction”钾恢,只需要把它修改成我們需要設(shè)置的類型即可手素。
需要注意的是,如果使用修改 redis.conf 的方式瘩蚪,當(dāng)設(shè)置完成之后需要重啟 Redis 服務(wù)器才能生效刑桑。
還有另一種簡單的修改內(nèi)存淘汰策略的方式,我們可以使用命令行工具輸入“config set maxmemory-policy noeviction”來修改內(nèi)存淘汰的策略募舟,這種修改方式的好處是執(zhí)行成功之后就會生效,無需重啟 Redis 服務(wù)器闻察。但它的壞處是不能持久化內(nèi)存淘汰策略拱礁,每次重啟 Redis 服務(wù)器之后設(shè)置的內(nèi)存淘汰策略就會丟失琢锋。
Redis 內(nèi)存淘汰策略使用了 LFU 和近 LRU 的淘汰算法,具體使用哪種淘汰算法呢灶,要看服務(wù)器是如何設(shè)置內(nèi)存淘汰策略的吴超,也就是要看“maxmemory-policy”的值是如何設(shè)置的。