redis記憶體淘汰機制

2021-09-27 04:45:15 字數 2226 閱讀 3039

當redis被當做快取來使用,當你新增資料時,讓它自動地**舊資料是件很方便的事情。這個行為在開發者社群非常有名,因為它是流行的memcached系統的預設行為。

lru是redis唯一支援的**方法。本頁面包括一些常規話題,redis的maxmemory指令用於將可用記憶體限制成乙個固定大小,還包括了redis使用的lru演算法,這個實際上只是近似的lru。

maxmemory配置指令用於配置redis儲存資料時指定限制的記憶體大小。通過redis.conf可以設定該指令,或者之後使用config set命令來進行執行時配置。

例如為了配置記憶體限制為100mb,以下的指令可以放在redis.conf檔案中。

maxmemory 100mb
設定maxmemory為0代表沒有記憶體限制。對於64位的系統這是個預設值,對於32位的系統預設記憶體限制為3gb。

當指定的記憶體限制大小達到時,需要選擇不同的行為,也就是策略。 redis可以僅僅對命令返回錯誤,這將使得記憶體被使用得更多,或者**一些舊的資料來使得新增資料時可以避免記憶體限制。

當maxmemory限制達到的時候redis會使用的行為由 redis的maxmemory-policy配置指令來進行配置。

以下的策略是可用的:

如果沒有鍵滿足**的前提條件的話,策略volatile-lru,volatile-random以及volatile-ttl就和noeviction 差不多了。

選擇正確的**策略是非常重要的,這取決於你的應用的訪問模式,不過你可以在執行時進行相關的策略調整,並且監控快取命中率和沒命中的次數,通過redisinfo命令輸出以便調優。

一般的經驗規則:

allkeys-lruvolatile-random策略對於當你想要單一的例項實現快取及持久化一些鍵時很有用。不過一般執行兩個例項是解決這個問題的更好方法。

為了鍵設定過期時間也是需要消耗記憶體的,所以使用allkeys-lru這種策略更加高效,因為沒有必要為鍵取設定過期時間當記憶體有壓力時。

理解**程序如何工作是非常重要的:

如果乙個命令的結果導致大量記憶體被使用(例如很大的集合的交集儲存到乙個新的鍵),不用多久記憶體限制就會被這個記憶體使用量超越。

redis的lru演算法並非完整的實現。這意味著redis並沒辦法選擇最佳候選來進行**,也就是最久未被訪問的鍵。相反它會嘗試執行乙個近似lru的演算法,通過對少量keys進行取樣,然後**其中乙個最好的key(被訪問時間較早的)。

不過從redis 3.0演算法已經改進為**鍵的候選池子。這改善了演算法的效能,使得更加近似真是的lru演算法的行為。

redis lru有個很重要的點,你通過調整每次**時檢查的取樣數量,以實現調整演算法的精度。這個引數可以通過以下的配置指令調整:

maxmemory-samples 5
redis為什麼不使用真實的lru實現是因為這需要太多的記憶體。不過近似的lru演算法對於應用而言應該是等價的。使用真實的lru演算法與近似的演算法可以通過下面的影象對比。

用於生成影象的redis服務被填充了指定數量的鍵。這些鍵將被從頭到尾訪問,所以當使用lru演算法時第乙個鍵是最佳的**候選鍵。接著新增超過50%的鍵,用於強制舊鍵被**。

你可以看到三種點在中, 形成了三種帶.

你可以看到,在都是五個取樣的時候redis 3.0比redis 2.8要好,redis2.8中在最後一次訪問之間的大多數的物件依然保留著。使用10個取樣大小的redis 3.0的近似值已經非常接近理論的效能。

注意lru只是個**鍵將如何被訪問的模型。另外,如果你的資料訪問模式非常接近冪定律,大部分的訪問將集中在乙個鍵的集合中,lru的近似演算法將處理得很好。

在模擬實驗的過程中,我們發現如果使用冪定律的訪問模式,則真實的lru演算法和近似的redis演算法幾乎沒有差別。

當然你可以提公升取樣大小到10,消耗更多的cpu時間以實現更真實的lru演算法,同時檢視下是否讓你的快取命中率有差別。

通過config set maxmemory-samples 命令在生產環境上設定不同的取樣大小是非常簡單的。

Redis 記憶體淘汰機制

摘要redis是一款優秀的 開源的記憶體資料庫,我在閱讀redis原始碼實現的過程中,時時刻刻能感受到redis作者為更好地使用記憶體而費盡各種心思,例如最明顯的是對於同一種資料結構在不同應用場景下提供了基於不同底層編碼的實現 如壓縮列表 跳躍表等 今天我們暫時放下對redis不同資料結構的 來一起...

redis 記憶體淘汰機制

redis記憶體淘汰指的是使用者儲存的一些鍵被可以被redis主動地從例項中刪除,從而產生讀miss的情況,那麼redis為什麼要有這種功能?這就是我們需要 的設計初衷。redis最常見的兩種應用場景為快取和持久儲存,首先要明確的乙個問題是記憶體淘汰策略更適合於那種場景?是持久儲存還是快取?記憶體的...

redis記憶體淘汰機制

redis記憶體淘汰 指的是使用者儲存的一些鍵被可以被redis 主動地 從例項中刪除,從而產生讀miss的情況,那麼redis為什麼要有這種功能?這就是我們需要 的設計初衷。redis最常見的兩種應用場景為 快取和 持久儲存 首先要明確的乙個問題是記憶體淘汰策略更適合於那種場景?是持久儲存還是快取...