1. 程式人生 > >redis(7)LRU緩存

redis(7)LRU緩存

3.0 mac img src width 實現 random 無法 bsp

一、LRU簡介

LRU是Least Recently Used的縮寫,即:最近最少使用。

它是內存管理中的一種頁面置換算法,對於在內存中但是又不用的數據塊,操作系統會根據哪些數據屬於LRU而將其移除內存而騰出空間來加載另外的數據。

二、redis LRU

官方文章:https://redis.io/topics/lru-cache#using-redis-as-an-lru-cache

redis常常被用作緩存,當有新的數據進來的時候會自動驅逐舊的數據。LRU是memcached 默認的驅逐策略,在開發者當中也是常常被提及的。

1)最大內存配置

在redis LRU緩存使用中,你需要配置最大內存。最大內存的作用是限制redis的內存使用,當內存使用接近最大值的時候就會根據驅逐策略進行舊數據驅逐。

你可以通過redis.conf配置:

macmemory 100mb

當然新版的redis可以通過命令來配置你可以使用命令

config set maxmemory ‘100mb‘

來配置

2)驅逐策略

最大內存限制了內存的使用以及臨界值,那麽驅逐策略則定義舊數據的驅逐方式,可用的策略有以下幾種:

1、noeviction: 當接近最大值的時候報錯

2、allkeys-lru: 移除所有keys中最近最少使用的key

3、volatile-lru: 移除所有攜帶過期時間(expire set)的keys中最少使用的key

4、allkeys-random: 隨機移除所有key

5、volatile-random: 隨機移除所有攜帶過期時間(expire set)的key

6、volatile-ttl: 移除攜帶過期時間(expire set),且剩余過期時間更短的key

3) 執行流程

1、當客戶端發送一個命令,需要新增數據

2、服務端會檢查內存使用情況,如將要大於限制,它就會根據驅逐策略驅逐key以釋放空間;

3、新命令被執行,以此類推。

4)近似LRU算法

事實上,Redis LRU 算法並不完全是LRU算法的實現,只能說是接近於LRU算法。尤其是在3.0版本以後已經非常接近LRU算法了。

Redis LRU 算法不會計算出所有keys當中最接近的(因為會比較耗內存),而是從所有key當中挑選出樣本,然後再挑選樣本的算法基礎上驅逐最接近的。

你可以配置樣本的數量:

maxmemory-samples 5

我們看官方網站提供的一張對比圖,LRU算法和Redis LRU算法的對比:

技術分享圖片

說明:1、綠色區域是新增數據;2、灰色區域是未驅逐數據;3、淺灰色區域是驅逐數據。

左上角是LRU算法,右上角是樣本為10的Redis3.0 LRU算法,左下角是樣本為5的Redis 2.8 LRU算法,右下角是樣本為5的Redis3.0 LRU。

很明顯,相同樣本的情況下,3.0版本較2.8版本有了很大程度的進步,更接近LRU算法。

在3.0版本中樣本為10較樣本為5的情況來說已經非常接近LRU算法。

三、Redis LFU

從redis4.0開始,提供了一種新的策略LFU (Least Frequently Used eviction mode),意識就是根據歷史的最少訪問頻率來決定驅逐的數據。這種策略的中心思想是認為,如果該數據歷史訪問頻率很高,那麽在未來的訪問頻率也會很高。

LFU有兩種選擇:

1)volatile-lfu: 從攜帶過期時間的keys中選擇歷史訪問最少的key

2) allkeys-lfu: 從所欲keys中選擇歷史訪問最少的key

四、LFU算法介紹:

在redis中每個對象都有24bits空間來記錄LRU/LFU信息:

當這24bits用作LFU時,其被分為兩部分:

1、高16位用來記錄訪問時間(單位:分鐘)

2、低8位用來記錄訪問頻率,簡稱(counter)

我們來看counter:基於概率的對數計數器

我們通常計數器就是直接遞增,但redis的計數器只有8bits最大值也就是2^8 - 1 = 255 ,如果采用直接遞增的方式那麽最多只能記錄255頻率。

因此,redis在這裏采用了概率對數的方法,在默認概率椅子配置:lfu_log_factor = 10 的情況下,8bits可以表示100萬的訪問頻率。

概率對數的算法讓8bits可以記錄很高的訪問頻率,但是如果計數器只做增長,就無法區分熱點key。可能出現的情況就是即使長時間沒有訪問,它的訪問頻率依然很高。

針對這種情況,redis提供了一個衰減因子lfu_decay_time(單位:分鐘),目的就是如果一個key長時間沒有被訪問那麽計數器就要減少,減少的值由衰減因子來控制。

redis的默認值為1,意思是如果N分鐘沒有被訪問,那麽計數器就減 1 * N。

上面的概率因子和衰減因子,redis都有默認值,當然也可以進行配置:

lfu-log-factor 10
lfu-decay-time 1

Redis LFU算法可以參考文章:https://yq.aliyun.com/articles/278922

redis(7)LRU緩存