如何用Redis做LRU Cache

2021-09-07 16:42:06 字數 2748 閱讀 1274

lru(least recently used)最近最少使用演算法是眾多置換演算法中的一種。

redis中有乙個maxmemory概念,主要是為了將使用的記憶體限定在乙個固定的大小。redis用到的lru 演算法,是一種近似的lru演算法。

上面已經說過maxmemory是為了限定redis最大記憶體使用量。有多種方法設定它的大小。其中一種方法是通過config set設定,如下:

127.0.0.1:6379>config get maxmemory

1) "maxmemory"

2) "0"

127.0.0.1:6379>config set maxmemory 100mb

ok127.0.0.1:6379>config get maxmemory

1) "maxmemory"

2) "104857600"

另一種方法是修改配置檔案redis.conf

maxmemory 100mb
注意,在64bit系統下,maxmemory設定為0表示不限制redis記憶體使用,在32bit系統下,maxmemory隱式不能超過3gb。 

當redis記憶體使用達到指定的限制時,就需要選擇乙個置換的策略。

當redis記憶體使用達到maxmemory時,需要選擇設定好的maxmemory-policy進行對老資料的置換。 

下面是可以選擇的置換策略:

設定maxmemory-policy的方法和設定maxmemory方法類似,通過redis.conf或是通過config set動態修改。

如果沒有匹配到可以刪除的key,那麼volatile-lruvolatile-randomvolatile-ttl策略和noeviction替換策略一樣——不對任何key進行置換。

選擇合適的置換策略是很重要的,這主要取決於你的應用的訪問模式,當然你也可以動態的修改置換策略,並通過用redis命令——info去輸出cache的命中率情況,進而可以對置換策略進行調優。

一般來說,有這樣一些常用的經驗:

volatile-lruvolatile-random經常在乙個redis例項既做cache又做持久化的情況下用到,然而,更好的選擇使用兩個redis例項來解決這個問題。

設定是失效時間expire會占用一些記憶體,而採用allkeys-lru就沒有必要設定失效時間,進而更有效的利用記憶體。

理解置換策略的執行方式是非常重要的,比如:

我們持續的寫資料會導致記憶體達到或超出上限maxmemory,但是置換策略會將記憶體使用降低到上限以下。

如果一次需要使用很多的記憶體(比如一次寫入乙個很大的set),那麼,redis的記憶體使用可能超出最大記憶體限制一段時間。

redis中的lru不是嚴格意義上的lru演算法實現,是一種近似的lru實現,主要是為了節約記憶體占用以及提公升效能。redis有這樣乙個配置——maxmemory-samples,redis的lru是取出配置的數目的key,然後從中選擇乙個最近最不經常使用的key進行置換,預設的5,如下:

maxmemory-samples 5

可以通過調整樣本數量來取得lru置換演算法的速度或是精確性方面的優勢。

redis不採用真正的lru實現的原因是為了節約記憶體使用。雖然不是真正的lru實現,但是它們在應用上幾乎是等價的。下圖是redis的近似lru實現和理論lru實現的對比:

測試開始首先在redis中匯入一定數目的key,然後從第乙個key依次訪問到最後乙個key,因此根據lru演算法第乙個被訪問的key應該最新被置換,之後再增加50%數目的key,導致50%的老的key被替換出去。 

在上圖中你可以看到三種型別的點,組成三種不同的區域:

理論lru實現就像我們期待的那樣,最舊的50%數目的key被置換出去,redis的lru將一定比例的舊key置換出去。

可以看到在樣本數為5的情況下,redis3.0要比redis2.8做的好很多,redis2.8中有很多應該被置換出去的資料沒有置換出去。在樣本數為10的情況下,redis3.0很接近真正的lru實現。

lru是乙個**未來我們會訪問哪些資料的模型,如果我們訪問資料的形式接近我們預想——冪律,那麼近似lru演算法實現將能處理的很好。

在模擬測試中我們可以發現,在冪律訪問模式下,理論lru和redis近似lru的差距很小或者就不存在差距。

如果你將maxmemory-samples設定為10,那麼redis將會增加額外的cpu開銷以保證接近真正的lru效能,可以通過檢查命中率來檢視有什麼不同。

通過config set maxmemory-samples動態調整樣本數大小,做一些測試驗證你的猜想。

我是如何用 redis 做實時訂閱推送的

小hub領讀 20w 的推送使用者,如何做到秒級併發完成,文中分別介紹了mq 傳統定時任務以及redis的sortset佇列三種方案,一一分析可行性,並且最後給出了redis的邏輯與部分 實現。你學會了嗎?前陣子開發了公司領劵中心的專案,這個專案是以 redis 作為關鍵技術落地的。其中有乙個功能叫...

如何用Python操作Redis

想要用python操作redis,就要掌握虛擬環境redis安裝以及開啟redis伺服器的命令.具體操作如下 伺服器端的命令為redis server 可以使用help檢視幫助文件 redis server help 推薦使用服務的方式管理redis服務 啟動 sudo service redis ...

如何用Jmeter做壓力測試

jmeter是乙個效能測試工具,同loadrunner類似,他功能較多,我們常用的功能是用jmeter模擬多瀏覽器對 做壓力測試。我們一般的 在進入業務功能前先需登入,然後才能訪問業務功能。下面介紹如何用jmeter登入系統再對主業務做壓力測試。1.執行jmeter 2.左邊樹將出現 測試計畫 工作...