redis過期key的刪除策略介紹
在使用redis的過程中,不免會產(chǎn)生過期的key,而這些key過期后并不會實時地馬上被刪除,當這些key數(shù)量累積越來越多,就會占用很多內(nèi)存,因此在redis底層同時使用了三種策略來刪除這些key。
第一種策略:被動刪除
當讀/寫一個key時,redis首先會檢查這個key是否存在,如果存在且已過期,則直接刪除這個key并返回nil
給客戶端。
第二種策略:定期刪除
redis中有一系列的定期任務(serverCron),這些任務每隔一段時間就會運行一次,其中就包含清理過期key的任務,運行頻率由配置文件中的hz
參數(shù)來控制,取值范圍1~500,默認是10,代表每秒運行10次。
清理過程如下:
- 遍歷所有的db
- 從db中設(shè)置了過期時間的key的集合中隨機檢查20個key
- 刪除檢查中發(fā)現(xiàn)的所有過期key
- 如果檢查結(jié)果中25%以上的key已過期,則繼續(xù)重復執(zhí)行步驟2-3,否則繼續(xù)遍歷下一個db
調(diào)大hz
將會提高redis定期任務的執(zhí)行頻率,如果你的redis中包含很多過期key的話,可以考慮將這個值調(diào)大,但要注意同時也會增加CPU的壓力,redis作者建議這個值不要超過100。
第三種策略:強制刪除
如果redis使用的內(nèi)存已經(jīng)達到maxmemory
配置的值時,會觸發(fā)強制清理策略,清理策略由配置文件的maxmemory-policy
參數(shù)來控制
有以下這些清理策略:
volatile-lru
:使用LRU算法對設(shè)置了過期時間的key進行清理(默認值)allkeys-lru
:使用LRU算法對所有key進行清理volatile-lfu
:使用LFU算法對設(shè)置了過期時間的key進行清理(redis 4.0版本開始支持)allkeys-lfu
:使用LFU算法對所有key進行清理(redis 4.0版本開始支持)volatile-random
:對所有設(shè)置了過期時間的key進行隨機清理allkeys-random
:從所有key進行隨機清理volatile-ttl
:清理生存時間最小的一部分keynoeviction
:不做任何清理,拒絕執(zhí)行所有的寫操作(如果需要保證數(shù)據(jù)的完整性,可以選擇這個)
為了節(jié)省內(nèi)存和性能上的考慮,上述的清理策略都不需要遍歷所有數(shù)據(jù),而是采用隨機采樣的方法,每次隨機取出特定數(shù)量(由maxmemory-samples
配置項控制,默認是5個)的key,然后在這些key中執(zhí)行LRU算法、RANDOM算法、或者是找出TTL時間最小的一個key,然后進行刪除。
注:這個清理過程是阻塞的,直到清理出足夠的內(nèi)存空間才會停止。
關(guān)于big key的清理
在刪除元素數(shù)量很多的集合(set/hash/list/sortedSet)時,無論是使用DEL
命令刪除還是redis為了釋放內(nèi)存空間而進行的刪除,在刪除這些big key的時候,會導致redis主線程阻塞。為了解決這個問題,在redis 4.0版本中,提供了lazy free(懶惰刪除)的特性。
使用lazy free刪除big key時,和一個O(1)指令的耗時一樣,亞毫秒級返回,然后把真正刪除key的耗時動作交由bio后臺子線程執(zhí)行。
UNLINK命令
UNLINK
命令是與DEL
一樣刪除key功能的lazy free實現(xiàn)。
唯一不同的是,UNLINK在刪除集合類型的鍵時,如果集合鍵的元素個數(shù)大于64個,會把真正的內(nèi)存釋放操作,交給單獨的后臺線程來操作,使用示例:
127.0.0.1:6379> UNLINK mylist (integer) 1
FLUSHALL/FLUSHDB命令
FLUSHALL
/FLUSHDB
命令也有l(wèi)azy free的實現(xiàn),在命令后加上ASYNC
關(guān)鍵字就可以,使用示例:
127.0.0.1:6379> FLUSHALL ASYNC
lazy free相關(guān)配置項
與lazy free相關(guān)的配置項有以下這些,默認值都是no,即關(guān)閉。
lazyfree-lazy-eviction
針對redis內(nèi)存使用達到maxmemory
,并設(shè)置有淘汰策略時,在淘汰鍵時是否采用lazy free機制。
注:如果此場景開啟lazy free,可能會使淘汰鍵的內(nèi)存釋放不及時,導致redis不能迅速將內(nèi)存使用下降到maxmemory以下。
lazyfree-lazy-expire
針對設(shè)置有過期時間的key,達到過期后,被redis清理刪除時是否采用lazy free機制,此場景建議開啟。
lazyfree-lazy-server-del
針對有些命令在處理已存在的鍵時,會帶有一個隱式的DEL鍵的操作。如RENAME
命令,當目標鍵已存在,redis會先刪除目標鍵,如果這些目標鍵是一個big key,那就會出現(xiàn)阻塞的性能問題。 此參數(shù)設(shè)置就是解決這類問題,建議開啟。
slave-lazy-flush
針對slave進行全量數(shù)據(jù)同步,slave在加載master的RDB文件前,會運行FLUSHALL
來清理自己的數(shù)據(jù)場景。
參數(shù)設(shè)置決定是否采用lazy free flush機制。如果內(nèi)存變動不大,建議可開啟。可減少全量同步耗時,從而減少主庫因輸出緩沖區(qū)爆漲引起的內(nèi)存使用增長。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Redis如何使用樂觀鎖(CAS)保證數(shù)據(jù)一致性
本文主要介紹了Redis如何使用樂觀鎖(CAS)保證數(shù)據(jù)一致性,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03Redis在Ubuntu系統(tǒng)上無法啟動的問題排查
這篇文章主要介紹了Redis在Ubuntu系統(tǒng)上無法啟動的問題排查,文中通過代碼示例給大家介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2024-08-08