Redis的記憶體淘汰策 LRU與LFU分析

2021-10-24 02:32:53 字數 1771 閱讀 5780

redis是基於記憶體儲存資料,當記憶體中儲存的資料較多時,為了避免記憶體被耗盡,redis就需要有一套機制來保證能夠自動清除那些被規定為可以被清除的資料,這種規定就可以定義為記憶體淘汰策略。

redis中的8種記憶體淘汰策略

不淘汰,滿了直接丟擲異常(maxmemory_no_eviction)

從所有key中,隨機刪除(maxmemory_allkeys_random)

從所有key中,採用lru方式刪除(maxmemory_allkeys_lru)

從設定了過期值的key中,隨機刪除(maxmemory_volatile_random)

從設定了過期值的key中,採用lru方式刪除(maxmemory_volatile_lru)

從所有key中,採用ttl方式刪除(優先淘汰快過期的)(maxmemory_volatile_ttl)

從設定了過期值的key中,採用lfu方式刪除(4.0版本新增)(maxmemory_volatile_lfu)

從所有key中,採用lfu方式刪除(4.0版本新增)(maxmemory_allkeys_lfu)

redis中的lru演算法

redis中採用的是一種近似lru演算法,目的是為了避免額外的記憶體消耗,如果嚴格按照lru演算法,就需要維護乙個雙向鍊錶,而redis中並沒有這樣做,redis中有乙個預設大小為16的池子(evpool_size),每次隨機抽取5個key(maxmemory_samples抽取數量可配置),讓抽取的key與池子中原有的key進行比較,只有時間小於池中的最小時間的key才會被放入池中,如果池子被放滿了,則將池中最大時間的key移除,當需要淘汰的時候,則將池中時間最小的key淘汰。

假設池子大小為6,每次隨機抽取1個key。

redis給每乙個key都預留了24bit的空間,用於記錄key的最後訪問時間

lfu演算法

lru演算法只是**最近被訪問的資料將來最有可能被訪問到,與訪問的頻率無關,而redis淘汰的主要目的是淘汰那些將來最不可能再被訪問的資料,那麼如果出現如下場景:

a—a---a—a---a—a---a

b------------------------------b

如果是根據lru演算法,被淘汰的將是a,因為在判定的那一時刻b是最近被訪問到的,而實際上b應該是符合將來最不可能再被訪問的資料。

這時候就要用lfu演算法了,lfu指的是最近最少使用,記錄的是一定時間內資料訪問的頻次,假設資料如果在一段時間內很少被訪問到,那麼將來也很少被訪問到。

lfu演算法也用到24bit的空間,但是24bit被拆分為兩部分,16bit用來記錄最後的遞減時間,8bit用來記錄訪問頻次

拆分為兩段的目的是為了能夠更加精確的進行過濾,假設乙個資料一段時間訪問的頻率非常的頻繁,但是之後的很長時間沒有再被訪問,如果只記錄訪問頻率,就不能滿足這樣的場景,所以還需要記錄上一次訪問的時間,這樣就可以通過訪問的時間來主動的遞減訪問頻率,以此適應短時間內訪問頻率很高,之後幾乎不被訪問的場景。

Redis記憶體淘汰策略與過期key處理策略

redis對於過期鍵有三種清除策略 1.被動刪除 當讀 寫乙個已經過期的key時,會觸發惰性刪除策略,直接刪除掉這個過期 key2.主動刪除 由於惰性刪除策略無法保證冷資料被及時刪掉,所以redis會定期主動淘汰一 批已過期的key 3.當前已用記憶體超過maxmemory限定時,觸發主動清理策略 ...

關於redis 超過最大記憶體限制,觸發淘汰策略說明

記憶體清理策略 volatile lru 對所有設定了過期時間的key使用lru演算法進行刪除 allkeys lru 對所有key使用lru演算法進行刪除 volatile lfu 對所有設定了過期時間的key使用lfu演算法進行刪除 allkeys lfu 對所有key使用lfu演算法進行刪除 ...

Redis的記憶體淘汰

redis定義了幾種策略用來處理這種情況 noeviction 預設策略 對於寫請求不再提供服務,直接返回錯誤 del請求和部分特殊請求除外 allkeys lru 從所有key中使用lru演算法進行淘汰 volatile lru 從設定了過期時間的key中使用lru演算法進行淘汰 allkeys ...