【Redis】內存淘汰策略讀後總結

Redis內存淘汰策略

Redis是基於內存的K-V數據庫,因爲系統的內存大小有限,所以在使用Redis的時候能配置Redis能使用的內存的大小。

Redis佔用內存的大小


  1. 通過配置文件修改
    通過修改在Redis安裝目錄下面的redis.conf配置文件中添加一下配置設置內存的大小
//設置redis佔用系統的內存爲100MB
maxmemory 100mb
  1. 通過指令修改
    Redis支持運行時通過命令動態修改內存大小
//設置Redis最大內存大小爲100MB
127.0.0.1:6379> config set maxmemory 100mb
//獲取設置的Redis能使用的內存大小
127.0.0.1:6379> config get maxmemory

如果不設置Redis內存的大小或者設置Redis內存的大小爲0,在64位系統下將不限制內存的大小,在32位操作系統下最多使用3GB內存

Redis的內存淘汰

既然Redis的內存可以設置,那麼配置的內存就有用完的時候,如果在Redis內存用盡的時候繼續往Redis中添加數據,這時Redis會如何處理?
Redis定義了幾種策略來處理這種情況:

  • noeviction(默認策略):對於寫請求不在提供服務,直接返回錯誤(DEL請求和部分特殊請求除外)
  • allkeys-lru:所有key使用LRU算法進行淘汰
  • volatile-lru:從設置了過期時間的key中使用LRU算法進行淘汰
  • allkeys-random:從所有key中隨機淘汰
  • volatile-random:從設置了過期時間的key中進行隨機淘汰
  • volatile-ttl:在設置了過期時間的key中,根據key的過期時間進行淘汰,越早過期的key越優先被淘汰
    當使用volatile-lru、volatile-random、volatile-ttl這三策略時,如果沒有key可以被淘汰,則和noeviction一樣返回錯誤。

如何獲取及設置內存淘汰策略

獲取當前內存淘汰策略:

127.0.0.1:6379> config get maxmemory-policy

通過配置文件設置淘汰策略(修改redis.conf文件):

maxmemory-policy allkeys-lru

通過命令修改淘汰策略:

127.0.0.1:6379> config set maxmemory-policy allkeys-lru

LRU算法

什麼是LRU?
LRU(Least Recently Used),即最近最少使用,是一種緩存置換算法。在使用內存作爲緩存的時候,緩存的大小一般是固定的,當緩存被佔滿,這時候繼續往內存中添加數據,就需要淘汰一部分老數據,釋放內存空間來存儲新的數據。這時候就可以使用LRU算法,其核心思想是:如果一個數據在最近一段時間沒有被用到,那麼將來被使用的可能性也很小,所以可以被淘汰。

LRU在Redis中的實現

近似LRU算法
Redis使用的是近似LRU算法,他和常規的LRU算法不太一樣,近似LRU算法通過隨機採樣法淘汰數據,每次隨機出5(默認)個key,從裏面淘汰掉最近最少使用的key。

可以通過maxmemory-samples參數修改採樣數量: 例:maxmemory-samples 10
maxmemory-samples配置的越大,淘汰結果越接近於嚴格的LRU算法。

Redis爲了實現近似LRU算法,給每個key增加了一個24bit的字段,用來存儲該key最後一次被訪問的時間。

Redis3.0對近似LRU算法進行了優化

Redis3.0對近似LRU算法進行了優化,新算法會維護一個候選池(大小爲16),池中的數據按訪問時間排序,第一次隨機選取key都會放入池中,隨後每次隨機選取的key只有在訪問時間小於池中的key的訪問時間時纔會被放入池中,知道侯選池被放滿。擋放滿後,如果有新的key需要放入,則將池中最後訪問時間最大(最近被訪問)的移除。
當需要被淘汰的時候,則直接從池中選取訪問時間最小(最久沒被訪問)的key進行淘汰。
經過對比後(Theoretical LRU、Approx LRU Redis3.0 10samples、Approx LRU Redis2.8 5samples、Approx LRU Redis3.0 5samples)得出結論是Redis3.0採樣數是10的時候,最接近於嚴格的LRU算法,同樣使用採樣數據爲5的時候,Redis3.0也優於2.8。

LFU算法

LFU算法是Redis4.0裏面最新的一種淘汰策略。它的全稱是Least Frequently Used,它的核心思想就是根據key的最近被訪問頻率進行淘汰,很少被訪問的優先被淘汰,被訪問的多的則被留下來。
LFU算法更好的表示了一個key的被訪問熱度,當使用LRU算法的時候,一個key很久沒被使用,剛剛偶爾使用了一次,那麼它就會被認爲是熱點數據,不會被淘汰,而有些key將來可能被訪問到,卻被淘汰了,如果使用LFU算法就不會出現這種情況,因爲其算法不會因使用一次就會將key定義爲熱點key。

LFU一共兩種策略:

  • volatile-lfu:在設置了過期時間的key中使用LFU算法淘汰key
  • allkeys-lfu:在所有的key中使用LFU算法進行淘汰數據

設置使用這兩種淘汰策略的時候要的一點是這兩種策略只能在Redis4.0及以上的版本設置,在Redis4.0以下的版本使用會報錯

爲何Redis使用近似LRU算法而不直接使用LRU算法?
因爲近似LRU算法只是把隨機採樣的key進行訪問時間排序,精確LRU需要全局排序,代價太大,結果相近,所以Redis選擇了近似LRU算法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章