將 redis 用作快取時, 如果記憶體空間用滿, 就會自動驅逐老的資料。 預設情況下 memcached 就是這種方式, 大部分開發者都比較熟悉。
lru是redis唯一支援的**演算法. 本文詳細介紹用於限制最大記憶體使用量的maxmemory
指令, 並深入講解 redis 所使用的近似lru演算法。
maxmemory
用於指定 redis 能使用的最大記憶體。既可以在redis.conf
檔案中設定, 也可以在執行過程中通過 config set 命令動態修改。
例如, 要設定 100mb 的記憶體限制, 可以在redis.conf
檔案中這樣配置:
maxmemory 100mb
將maxmemory
設定為0
, 則表示不進行記憶體限制。當然, 對32位系統來說有乙個隱性的限制條件: 最多 3gb 記憶體。
當記憶體使用達到最大限制時, 如果需要儲存新資料, 根據配置的策略(policies)的不同, redis可能直接返回錯誤資訊, 或者刪除部分老的資料。
達到最大記憶體限制時(maxmemory
), redis 根據maxmemory-policy
配置的策略, 來決定具體的行為。
當前版本,redis 3.0 支援的策略包括:
如果沒有設定expire的key, 不滿足先決條件(prerequisites); 那麼volatile-lru,volatile-random和volatile-ttl策略的行為, 和noeviction(不刪除)基本上一致。
您需要根據系統的特徵, 來選擇合適的驅逐策略。 當然, 在執行過程中也可以通過命令動態設定驅逐策略, 並通過 info 命令監控快取的 miss 和 hit, 來進行調優。
一般來說:
volatile-lru和volatile-random策略主要應用場景是: 既有快取,又有持久key的例項中。 一般來說, 像這類場景, 應該使用兩個單獨的 redis 例項。
值得一提的是, 設定expire
會消耗額外的記憶體, 所以使用allkeys-lru策略, 可以更高效地利用記憶體, 因為這樣就可以不再設定過期時間了。
驅逐過程可以這樣理解:
在這個過程中, 記憶體使用量會不斷地達到 limit 值, 然後超過, 然後刪除部分 key, 使用量又下降到 limit 值之下。
如果某個命令導致大量記憶體占用(比如通過新key儲存乙個很大的set), 在一段時間內, 可能記憶體的使用量會明顯超過 maxmemory 限制。
redis 使用的並不是完全lru演算法。自動驅逐的 key , 並不一定是最滿足lru特徵的那個. 而是通過近似lru演算法, 抽取少量的 key 樣本, 然後刪除其中訪問時間最古老的那個key。
驅逐演算法, 從 redis 3.0 開始得到了巨大的優化, 使用 pool(池子) 來作為候選. 這大大提公升了演算法效率, 也更接近於真實的lru演算法。
在 redis 的 lru 演算法中, 可以通過設定樣本(sample)的數量來調優演算法精度。 通過以下指令配置:
maxmemory-samples 5
為什麼不使用完全lru實現? 原因是為了節省記憶體。但 redis 的行為和lru基本上是等價的. 下面是 redis lru 與完全lru演算法的乙個行為對比圖。
測試過程中, 依次從第乙個 key 開始訪問, 所以最前面的 key 才是最佳的驅逐物件。
從圖中可以看到三種型別的點, 構成了三個不同的條帶。
在純粹的lru演算法實現中, 前半部分舊的key被釋放了。而 redis 的 lru 演算法只是將時間較長的 key 較大概率地(probabilistically)釋放了。
如你所見, redis 3.0 中, 5樣本的效果比 redis 2.8 要好很多。 當然, redis 2.8 也不錯,最後訪問的key基本上都還留在記憶體中. 在 redis 3.0 中使用 10 樣本時, 已經非常接近純粹的lru演算法了。
注意,lru只是用來**將來可能會繼續訪問某個key的乙個概率模型. 此外,如果資料訪問的情況符合冪律分布(power law), 那麼對於大部分的請求來說, lru都會表現良好。
在模擬中, 我們發現, 如果使用冪律方式訪問, 純粹的lru和redis的結果差別非常, 甚至看不出來。
當然也可以將樣本數量提高到10, 以額外消耗一些cpu為代價, 使得結果更接近於真實的lru, 並通過 cache miss 統計資訊來判斷差異。
設定樣本大小很容易, 使用命令config set maxmemory-samples
即可。
配置Redis作為快取(六種淘汰策略)
將 redis 用作快取時,如果記憶體空間用滿,就會自動驅逐老的資料。預設情況下 memcached 就是這種方式,大部分開發者都比較熟悉。lru是redis唯一支援的 演算法.本文詳細介紹用於限制最大記憶體使用量的 maxmemory 指令,並深入講解 redis 所使用的近似lru演算法。max...
Redis六種淘汰策略
將 redis 用作快取時,如果記憶體空間用滿,就會自動驅逐老的資料。預設情況下 memcached 就是這種方式,大部分開發者都比較熟悉。lru是redis唯一支援的 演算法.本文詳細介紹用於限制最大記憶體使用量的 maxmemory 指令,並深入講解 redis 所使用的近似lru演算法。max...
Redis六種淘汰策略
將redis用作快取時,如果記憶體空間用滿,就會自動驅逐老的資料。預設情況下 memcached就是這就方式。lru是redis唯一支援的 演算法,本文講解限制最大記憶體使用量的maxmemory指令,並深入講解redis所使用的近似lru演算法。maxmemory用於指定redis能使用的最大記憶...