Redis內(nèi)存回收用法及說明
Redis可以通過修改配置文件maxmemory為Redis設(shè)置最大內(nèi)存空間占用,當(dāng)內(nèi)存存儲達(dá)到上限時,就無法存儲更多數(shù)據(jù)了。
Redis提供了過期策略和淘汰策略來避免內(nèi)存存儲達(dá)到上限。
一、過期策略
過期策略就是通過expire命令給key設(shè)置TTL,key過期時,key對應(yīng)的內(nèi)存會被釋放。
redisDB維護(hù)兩個Dict:dict、expires,dict記錄所有redisObject-內(nèi)存首址鍵值對、expires記錄設(shè)置了過期時間的redisObject-過期時間鍵值對。
1.惰性刪除
惰性刪除在訪問(CRUD)key時執(zhí)行:首先根據(jù)key從dict中找到對應(yīng)的redisObject,然后檢查key記錄在expires中的TTL,如果過期那么釋放key的內(nèi)存空間。
存在的問題:如果key過期了但是永遠(yuǎn)不會被訪問,那么惰性刪除策略下該key的內(nèi)存空間永遠(yuǎn)不會被釋放。
2.周期刪除
為所有key設(shè)置同一個定時任務(wù),周期性的抽樣部分key,檢查是否過期,如果過期執(zhí)行刪除操作:
SLOW模式:redis單線程初始化時(初始化epoll階段)設(shè)置server.hz頻率(默認(rèn)100ms)定期檢查并清理過期key,不在主線程main函數(shù)中。
- 執(zhí)行周期為100ms,執(zhí)行清理耗時不能超過25%即25ms
- 首先逐個遍歷db,每次取20個key檢查并清理過期key
- 如果時間未達(dá)到25ms且剛才檢查的過期key比例超過10%,再取20個key檢查并清理。
- (感覺這個任務(wù)每100ms執(zhí)行一次的話,如果不是異步的,應(yīng)該要搶占主單線程的CPU)
FAST模式:每次redis單線程調(diào)用epoll_wait阻塞前都會先檢查并清理部分過期key(2ms左右)
- 因為位于主線程的main代碼中,所以執(zhí)行周期為兩次調(diào)用epoll_wait的間隔,但如果間隔低于2ms那么不會執(zhí)行FAST清理直到兩次FAST間隔大于2ms。,每次清理耗時不能超過1ms
- 首先逐個遍歷db,每次取20個key檢查并清理過期key
- 如果時間未達(dá)到25ms且剛才檢查的過期key比例超過10%,再取20個key檢查并清理。
二、淘汰策略
淘汰策略就是Redis內(nèi)存使用達(dá)到閾值時,主動挑選部分key刪除以釋放內(nèi)存。
淘汰策略在主線程解析命令后處理命令前執(zhí)行,配置maxmemory-policy:
- noeviction:不淘汰任何key,內(nèi)存滿時不允許寫入新數(shù)據(jù),默認(rèn)策略。
- volatile-ttl:對設(shè)置了TTL的key淘汰,TTL越小越先被淘汰
- allkeys-random:對全體key(dict哈希表),隨機(jī)淘汰。
- volatile-random:對設(shè)置了TTL的key(expires哈希表),隨機(jī)淘汰。
- allkeys-lru:對全體key(dict哈希表),使用LRU算法進(jìn)行淘汰。
- volatile-lru:對設(shè)置了TTL的key(expires哈希表),使用LRU算法進(jìn)行淘汰。
- allkeys-lfu:對全體key(dict哈希表),使用LFU算法進(jìn)行淘汰。
- volatile-lfu:對設(shè)置了TTL的key(expires哈希表),使用LFU算法進(jìn)行淘汰。
LRU:當(dāng)前時間減最近一次訪問時間,值越大優(yōu)先淘汰。
LFU:訪問次數(shù)越少優(yōu)先淘汰。
key的訪問次數(shù)和訪問時間都會封裝在redisObject對象中:ptr指向key-value具體值

邏輯訪問次數(shù):由于8bit只能記錄實際訪問次數(shù)0~255,對于熱key來說遠(yuǎn)遠(yuǎn)不夠,所以使用邏輯訪問次數(shù)
- 當(dāng)key被訪問時,生成一個0~1之間的隨機(jī)數(shù)R
- 計算P=1/(舊訪問次數(shù)*10+1)
- 如果R<P,計數(shù)器+1,最大不超過255
- 為了防止key長時間不訪問但訪問次數(shù)一直不變,訪問次數(shù)隨時間衰減,距離上一次訪問間隔每隔1分鐘計數(shù)器-1
也就是說邏輯訪問次數(shù)越大,P越小,R<P的概率越小,計數(shù)器越難+1。

總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Redis入門教程_動力節(jié)點Java學(xué)院整理
Redis是一款開源的、高性能的鍵-值存儲(key-value store)。下面通過本文大家分享Redis入門教程,感興趣的朋友參考下吧2017-08-08
Redis面試必備之緩存設(shè)計規(guī)范與性能優(yōu)化詳解
你是否在使用Redis時,不清楚Redis應(yīng)該遵循的設(shè)計規(guī)范而苦惱,你是否在Redis出現(xiàn)性能問題時,不知道該如何優(yōu)化而發(fā)愁,快跟隨小編一起學(xué)習(xí)起來吧2024-03-03
Redis熱點Key獨立集群實現(xiàn)方案(核心思路)
文章介紹了Redis熱點Key獨立集群實現(xiàn)方案,通過多實例配置、靈活的路由規(guī)則和統(tǒng)一的訪問接口,實現(xiàn)資源隔離、靈活擴(kuò)展、高可用性和統(tǒng)一管理,部署架構(gòu)、注意事項和擴(kuò)展建議也為方案的實施提供了指導(dǎo),感興趣的朋友跟隨小編一起看看吧2026-01-01

