Redis6.0.6的三大記憶體過期策略和八大淘汰策略

2022-09-13 12:01:36

一、前言

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就有了進一步的瞭解,謝謝大家跟著小編一起走下來,看到這裡還不動一下你的發財小手點個關注哈!!


有緣人才可以看得到的哦!!!

點選存取!小編自己的網站,裡面也是有很多好的文章哦!