Redis6.0.6的三大記憶體過期策略和八大淘汰策略
一、前言
Redis在我們日常開發中是經常用到的,Redis也是功能非常強大,可以進行快取,還會有一些排行榜、點贊、消息隊列、購物車等等;當然還有分散式鎖Redisson
,我們使用肯定少不了集群!小編最近學習到一些記憶體如果滿了Redis是怎麼操作呢?肯定像我們JVM
一樣,有回收或者淘汰的機制!今天小編和大家一起學習一下,小編也是看了陽哥的課,覺得講的很好,記錄一下,希望可以幫助到大家!!
二、自己配置Redis記憶體大小
redis安裝上,如果你不配置的話,默認就是按你的電腦記憶體的大小。
我們打開配置文件看一下哈!這裡以6.0.6配置文件為例
打開redis.conf文件:856行
:
我們可以設置大小,我們可以看到是以位元組為單位的哈!
maxmemory <bytes>
我們可以使用命令查詢記憶體大小:
127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "0"
不配置默認為0使用電腦最大記憶體。
當然也可以通過命令進行設置:
127.0.0.1:6379> config set maxmemory 2
OK
127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "2"
127.0.0.1:6379> set k1 wang
(error) OOM command not allowed when used memory > 'maxmemory'.
根據測試:我們發現redis也會像JVM一樣報OOM異常
心得: 我們一般不會調整Redis的記憶體大小,如果調也是一般像HashMap的載入因子一樣,也就是3/4即可
三、三大過期策略
三大過期策略:定時刪除、惰性刪除、定期刪除
過期策略存在原因:
Redis不可能時時刻刻遍歷所有被設置了生存時間的key,來檢測數據是否已經到達過期時間,然後對它進行刪除。
1. 定時刪除
定時刪除又名立即刪除:能保證記憶體中數據的最大新鮮度,因為它保證過期鍵值會在過期後馬上被刪除
,其所佔用的記憶體也會隨之釋放。但是立即刪除對cpu是最不友好
的。因為刪除操作會佔用cpu的時間,如果剛好碰上了cpu很忙的時候,比如正在做交集或排序等計算的時候,就會給cpu造成額外的壓力,讓CPU心累,時時需要刪除,忙死。
這會產生大量的性能消耗,同時也會影響數據的讀取操作
。
2. 惰性刪除
數據到達過期時間,不做處理。等下次訪問該數據時,如果未過期,返回數據;發現已過期,刪除,返回不存在
。
惰性刪除策略的缺點是,它對記憶體是很不友好的
。
如果一個鍵已經過期,而這個鍵又仍然保留在資料庫中,那麼只要這個過期鍵不被刪除,它所佔用的記憶體就不會釋放。
在使用惰性刪除策略時,如果資料庫中有非常多的過期鍵,而這些過期鍵又恰好沒有被訪問到的話,那麼它們也許永遠也不會被刪除(除非用戶手動執行FLUSHDB),我們甚至可以將這種情況看作是一種記憶體泄漏 – 無用的垃圾數據佔用了大量的記憶體,而伺服器卻不會自己去釋放它們,這對於運行狀態非常依賴於記憶體的Redis伺服器來說,肯定不是一個好消息。
3. 定期刪除
定期刪除策略是前兩種策略的折中:
定期刪除策略每隔一段時間執行一次刪除過期鍵操作,並通過限制刪除操作執行的時長和頻率來減少刪除操作對CPU時間的影響
。
周期性輪詢Redis庫中的時效性數據,來用隨機抽取的策略,利用過期數據佔比的方式控制刪除頻度
特點1:CPU性能佔用設置有峰值,檢測頻度可自定義設置
特點2:記憶體壓力不是很大,長期佔用記憶體的冷數據會被持續清理
4. 附例子:
redis默認每個100ms檢查,是否有過期的key,有過期key則刪除。
注意:redis不是每隔100ms將所有的key檢查一次而是隨機抽取進行檢查
(如果每隔100ms,全部key進行檢查,redis直接進去ICU)。因此,如果只採用定期刪除策略,會導致很多key到時間沒有刪除
。
定期刪除策略的難點是確定刪除操作執行的時長和頻率:如果刪除操作執行得太頻繁,或者執行的時間太長,定期刪除策略就會退化成定時刪除策略,以至於將CPU時間過多地消耗在刪除過期鍵上面。如果刪除操作執行得太少,或者執行的時間太短,定期刪除策略又會和惰性刪除束略一樣,出現浪費記憶體的情況。因此,如果採用定期刪除策略的話,伺服器必須根據情況,合理地設置刪除操作的執行時長和執行頻率。
5. 總結
定時刪除 :對CPU不友好,用處理器性能換取存儲空間(拿時間換空間)
惰性刪除:對memory不友好,用存儲空間換取處理器性能(拿空間換時間)
定期刪除:周期性抽查存儲空間,隨機抽查,重點抽查(存在漏網之魚)
6.思考
我們會發現,三種情況都存在瑕疵,如果數據量大,一定會出現記憶體滿了,報OOM!所以我們下面引出八大淘汰策略!!
四、八大淘汰策略
我們還是打開redis.conf
配置文件,找到861
行:
# volatile-lru -> Evict using approximated LRU, only keys with an expire set.
# allkeys-lru -> Evict any key using approximated LRU.
# volatile-lfu -> Evict using approximated LFU, only keys with an expire set.
# allkeys-lfu -> Evict any key using approximated LFU.
# volatile-random -> Remove a random key having an expire set.
# allkeys-random -> Remove a random key, any key.
# volatile-ttl -> Remove the key with the nearest expire time (minor TTL)
# noeviction -> Don't evict anything, just return an error on write operations.
我們來翻譯一下哈:
volatile-lru:當記憶體放不下新添加的數據時,從設置了過期時間的key中使用LRU(最近最少使用)演算法進行刪除key;
allkeys-lru:當記憶體放不下新添加的數據時,從所有key中使用LRU(最近最少使用)演算法進行刪除key。
volatile-lfu:當記憶體放不下新添加的數據時,從設置了過期時間的key中,使用LFU(最近頻繁使用)演算法進行刪除key。
allkeys-lfu:當記憶體放不下新添加的數據時,從所有key中使用LFU(最近頻繁使用)演算法進行刪除key;
volatile-random:當記憶體放不下新添加的數據時,從設置了過期時間的key中,隨機刪除key;。
allkeys-random:當記憶體放不下新添加的數據時,從所有key中隨機刪除key。
volatile-ttl:當記憶體放不下新添加的數據時,在設置了過期時間的key中,根據過期時間進行淘汰,越早過期的優先被刪除key;
noeviction:當記憶體放不下新添加的數據時,新寫入操作會報錯。默認策略
五、手動配置淘汰策略
打開redis.conf
配置文件找到:887
行,把注釋去掉,添加自己需要的淘汰策略
maxmemory-policy noeviction
當然我們也可以使用命令進行修改:
127.0.0.1:6379> config set maxmemory-policy allkeys-Lru
OK
127.0.0.1:6379> config get maxmemory-policy
1) "maxmemory-policy"
2) "allkeys-lru"
六、總結
這樣我們對Redis就有了進一步的了解,謝謝大家跟著小編一起走下來,看到這裡還不動一下你的發財小手點個關注哈!!
有緣人才可以看得到的哦!!!