把Redis用作LRU緩存

把Redis用作LRU緩存

當Redis被用作緩存時浊仆,當你添加新的數(shù)據(jù)時誓军,通常可以很方便的使它自動的淘汰舊的數(shù)據(jù)面睛。這個行為在開發(fā)者社區(qū)中很知名,因為它是流行的memcached系統(tǒng)中一個默認的行為尊搬。

LRU實際上只是支持淘汰的方法之一叁鉴。本頁覆蓋了更多的Redismaxmemory指令的通用話題,它用于限制內(nèi)存使用總數(shù)為一個固定的值佛寿,并且也深入介紹了Redis中的LRU算法使用幌墓,實際上是精確的LRU算法的近似方法。

從Redis4.0版本開始狗准,一個新的LFU(最不經(jīng)常使用)淘汰政策被引入克锣。它在本文檔中一個獨立的部分中被介紹。

最大內(nèi)存配置指令

maxmemory配置指令被用于配置Redis的數(shù)據(jù)集使用一個特定的內(nèi)存總量腔长∠睿可以使用redis.conf文件來配置指令,或者稍后使用CONFIG SET命令實時的配置捞附。

例如巾乳,為了配置內(nèi)存限制為100MB,可以在redis.conf文件中使用下面的指令鸟召。

maxmemory 100mb

設(shè)置maxmemory為0會導(dǎo)致沒有內(nèi)存限制胆绊。在64位系統(tǒng)中默認是沒有限制的,但是在32位系統(tǒng)中使用的隱式內(nèi)存限制是3GB欧募。

當即將到指定的內(nèi)存時压状,可以在不同的行為(策略)之間做出選擇。對于那些可能會導(dǎo)致更多內(nèi)存使用的命令Redis可以只返回錯誤跟继,或者在每次添加新的數(shù)據(jù)時种冬,可以淘汰一些舊的數(shù)據(jù)從而讓內(nèi)存回到一個特定的限制值。

回收策略

maxmemory限制到達時舔糖,Redis執(zhí)行的準確的行為是使用maxmemory-policy配置的指令娱两。

下面的策略是可用的:

  • 不回收:當?shù)竭_限制的內(nèi)存,客戶端嘗試執(zhí)行可能會導(dǎo)致使用更多內(nèi)存的命令(大部分是寫命令金吗,但是DEL和其他一些列外)時十兢,返回錯誤。
  • alleys-lru: 嘗試先移除最近最少使用(LRU)的鍵來回收鍵摇庙,為新添加的數(shù)據(jù)制造內(nèi)存空間旱物。
  • volatile-lru:嘗試移除最近最少使用(LRU)的鍵來回收鍵,但是僅在有過期時間的鍵中卫袒,為新添加的數(shù)據(jù)制造內(nèi)存空間异袄。
  • alleys-random: 隨機回收鍵,為新添加的數(shù)據(jù)制造空間玛臂。
  • volatile-random:隨機回收鍵烤蜕,為新添加的數(shù)據(jù)制造空間封孙,但是僅淘汰擁有過期時間的鍵。
  • volatile-ttl:使用過期時間淘汰鍵讽营,并且嘗試先淘汰具有較短生存期(TTL)的鍵虎忌,為新添加的數(shù)據(jù)創(chuàng)造空間。

如果沒有匹配先決條件的鍵可以被回收時橱鹏,策略 volatile-lru, volatile-randomvolatile-ttl 的行為像noeviction膜蠢。

挑選合適的回收策略是重要的,依賴于你的應(yīng)用的訪問模式莉兰,盡管你可以在應(yīng)用運行時重新配置策略挑围,并且使用Redis的INfO來監(jiān)視緩存丟失和命中的數(shù)量以便于調(diào)整你的設(shè)置。

一般來說的經(jīng)驗法則:

  • 當你期待受歡迎的請求是冪律分布時糖荒,也就是說杉辙,你期待元素的子集將會比其他子集被更頻繁的訪問時使用allkeys-lru策略。當你不確定時捶朵,這個一個好的選擇蜘矢。
  • 如果你有一個所有的鍵被連續(xù)不斷掃描的循環(huán)訪問時,或者當你期待分布是統(tǒng)一時综看,使用allkeys-random策略(所有的元素以相同的概率被訪問)品腹。
  • 如果想要通過在創(chuàng)建緩存對象時使用不同的TTL來提示Redis哪些是過期的候選者,那么使用volatile-ttl红碑。

volatile-lruvolatile-random策略在你想使用一個單實例同時用于緩存和擁有一系列持久化鍵時非常有用舞吭。然而,運行兩個Redis實例來解決這個問題通常是一個更好的主意析珊。

值得注意的是镣典,給一個鍵設(shè)置過期時間是需要占用內(nèi)存的,因而使用一個類似于allkeys-lru的策略更有內(nèi)存效率唾琼,因為在有內(nèi)存壓力時給一個鍵設(shè)置一個過期時間然后回收是不必要的。

回收進程如何工作

重要的是理解回收處理過程是這樣運作的:

  • 客戶端運行了一個新的命令澎剥,導(dǎo)致更多的數(shù)據(jù)被添加锡溯。
  • Redis檢查內(nèi)存使用量,如果超過了maxmemory限制哑姚,它就會依照策略回收鍵祭饭。
  • 執(zhí)行一個新的命令,重復(fù)以上叙量。

因此我們持續(xù)的跨越內(nèi)存限制的邊界倡蝙,通過超出它,然后通過回收鍵而回到限制以下绞佩。

如果一個鍵導(dǎo)致大量的內(nèi)存被使用(就像一個大的集合交叉保存到一個新鍵上)寺鸥,在一段時間內(nèi)內(nèi)存限制可以被顯著的超過猪钮。

近似LRU算法

Redis的LRU算法不是一個精確的實現(xiàn)。這意味著Redis不能夠選出最佳候選人來回收胆建,也就是烤低,過去訪問最多的訪問權(quán)限。相反笆载,它是嘗試運行一個近似的LRU算法扑馁,通過取樣一小部分鍵,然后回收樣本中最合適(擁有最古老訪問時間)的那一個凉驻。

然而腻要,從Redis3.0版本開始算法已經(jīng)被改進成候選人池供回收。這提高了算法的性能涝登,使其能夠更接近于真實LRU算法的行為雄家。

Redis LRU算法的重要之處是,可以通過改變樣本的數(shù)量來調(diào)整算法的精度缀拭,以檢查每一次的回收咳短。這個參數(shù)受下面的配置指令控制:

maxmemory-samples 5

Redis不用真正的LRU實現(xiàn)的原因是它會消耗更多的內(nèi)存。然而蛛淋,這種近似對于使用Redis的應(yīng)用實際上是等價的咙好。下面就是使用Redis LRU近似算法與使用真實LRU的對比圖。


LRU comparison

生成上述圖像的測試用一個給定數(shù)字的鍵填充了一個Redis服務(wù)褐荷。這些鍵從第一個到最后一個被訪問勾效,因此,最早的鍵是LRU算法回收的最好的候選人叛甫。稍后层宫,添加了超過50%的鍵,強迫超過一半的舊的鍵被回收其监。

你可以看到圖像中有3種類型的點萌腿,組成3個明顯的區(qū)域。

  • 淺灰色的區(qū)域是被回收的對象抖苦。
  • 灰色的區(qū)域是沒有被回收的對象毁菱。
  • 綠色的區(qū)域是被添加的對象。

在理論上LRU實現(xiàn)期待的是锌历,在舊的鍵中贮庞,最早的那一半將會被過期。但Redis的LRU算法將僅有概率的過期舊的鍵究西。

如你所見窗慎,與Redis2.8相比,Redis3.0使用5個樣本時做的要更好,但是大多數(shù)最新訪問的對象仍然在Redis2.8中保留了下來遮斥。Redis3.0使用10個樣本時的近似值已經(jīng)非常接近于Redis3.0的理論上的性能峦失。

注意,LRU僅是一個模型伏伐,用于預(yù)測一個給定的鍵將來被訪問的可能性宠进。此外,如果你的數(shù)據(jù)訪問模式很接近于冪律藐翎,在集合中的鍵的大部分訪問使用LRU近似算法將會處理的很好材蹬。

在模擬中我們發(fā)現(xiàn)使用冪律訪問模式時,真LRU算法和Redis近似算法的差異非常小或者不存在吝镣。

然而堤器,為了接近真的LRU,你可以提升樣本量到10末贾,這樣會使用一點額外的CPU資源闸溃,然后檢查緩存丟失率會有什么不同。

可以通過CONFIG SET maxmemory-samples <count>命令拱撵,在生產(chǎn)環(huán)境中使用不同的樣本值做實驗辉川,這非常簡單。

新的LFU模式

從Redis4.0開始拴测,可以使用一個新的最少使用頻率回收模式乓旗。在某些下這個模式可以工作的更好(提供一個更好的命中/丟失率),因為使用LFU集索,Redis將會嘗試追蹤項目的訪問頻率屿愚,所以使用頻率非常小的將會被回收,同時使用非常頻繁的會有更多的機會被保存在內(nèi)存中务荆。

如果你在思考LRU妆距,一個最近訪問過但是實際上幾乎從未被請求的項目,將不會被過期函匕,因此有一個風險是回收一個未來有很多機會被訪問的鍵娱据。LFU不會有這個問題,并且通常應(yīng)該對不同的訪問模式適配的更好盅惜。

配置LFU有以下幾種模式:

  • volatile-lfu 使用近似LFU算法回收擁有過期時間的鍵
  • allkeys-lfu 使用近似LFU算法回收所有鍵

LFU類似于LRU:它使用一個被稱為莫里斯計數(shù)器的概率計數(shù)器中剩,以便評估對象的訪問頻率,每個對象僅使用少量的字節(jié)酷窥,組合一個衰減周期,因此計數(shù)器隨著時間流逝而減少:在某個時間點我們不再認為這個鍵是被頻繁訪問的伴网,即使是在過去蓬推,因此這個算法可以適應(yīng)訪問模式的改變。

這些信息的取樣過程跟LRU的取樣過程(在本文檔前面的部分已經(jīng)解釋過)很類似澡腾,以便選擇一個候選對象回收沸伏。

然而糕珊,與LRU不同的是,LFU有確定的調(diào)節(jié)參數(shù):例如毅糟,如果一個項目不再被訪問红选,需要以多快的頻率降低它的等級?為了更好的適配特定案例的算法姆另,它也可以調(diào)節(jié)莫里斯計數(shù)器的范圍喇肋。

Redis4.0被默認設(shè)置為:

  • 讓計數(shù)器飽和,大概100萬請求迹辐。
  • 每分鐘把計數(shù)器衰減一次

那些是合理的值并經(jīng)過測試試驗過的蝶防,但是用戶可能想玩一下配置以選擇最佳值。

在源碼發(fā)行版的redis.conf文件中可以找到如何調(diào)整這些參數(shù)的的介紹明吩,不過簡而言之间学,它們是:

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

衰減時間是一個很明顯的,當采樣和發(fā)現(xiàn)超過這個值時印荔,它是一個計數(shù)器必須衰減的分鐘數(shù)低葫。一個特別的值0意味著:每次掃描時計數(shù)器都衰減,用途不是很大仍律。

計數(shù)器對數(shù)因子改變需要多少次命中才能充滿頻率計數(shù)器嘿悬,取值范圍在0-255. 較高的因子,需要更多的訪問以達到最大值染苛。較低的因子鹊漠,是低訪問計數(shù)器的更好的解決方案,符合下面的表格:

+--------+------------+------------+------------+------------+------------+
| factor | 100 hits   | 1000 hits  | 100K hits  | 1M hits    | 10M hits   |
+--------+------------+------------+------------+------------+------------+
| 0      | 104        | 255        | 255        | 255        | 255        |
+--------+------------+------------+------------+------------+------------+
| 1      | 18         | 49         | 255        | 255        | 255        |
+--------+------------+------------+------------+------------+------------+
| 10     | 10         | 18         | 142        | 255        | 255        |
+--------+------------+------------+------------+------------+------------+
| 100    | 8          | 11         | 49         | 143        | 255        |
+--------+------------+------------+------------+------------+------------+

因此茶行,基本上來講躯概,這個因子是分別低訪問量 VS 高訪問量之間更好的一種權(quán)衡。更多的信息可以在redis.conf文件自身的描述中看到畔师。

因為LFU是一個新的特征娶靡,我們都很感激對它在你的使用場景下與LRU相比表現(xiàn)如何的反饋。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末看锉,一起剝皮案震驚了整個濱河市姿锭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌伯铣,老刑警劉巖呻此,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異腔寡,居然都是意外死亡焚鲜,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忿磅,“玉大人糯彬,你說我怎么就攤上這事〈兴” “怎么了撩扒?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長吨些。 經(jīng)常有香客問我搓谆,道長,這世上最難降的妖魔是什么锤灿? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任挽拔,我火速辦了婚禮,結(jié)果婚禮上但校,老公的妹妹穿的比我還像新娘螃诅。我一直安慰自己,他們只是感情好状囱,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布术裸。 她就那樣靜靜地躺著,像睡著了一般亭枷。 火紅的嫁衣襯著肌膚如雪袭艺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天叨粘,我揣著相機與錄音猾编,去河邊找鬼。 笑死升敲,一個胖子當著我的面吹牛答倡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播驴党,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼瘪撇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了港庄?” 一聲冷哼從身側(cè)響起倔既,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鹏氧,沒想到半個月后渤涌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡把还,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年实蓬,在試婚紗的時候發(fā)現(xiàn)自己被綠了稿存。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡瞳秽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出率翅,到底是詐尸還是另有隱情练俐,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布冕臭,位于F島的核電站腺晾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏辜贵。R本人自食惡果不足惜悯蝉,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望托慨。 院中可真熱鬧鼻由,春花似錦、人聲如沸厚棵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婆硬。三九已至狠轻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間彬犯,已是汗流浹背向楼。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谐区,地道東北人湖蜕。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像卢佣,于是被迫代替她去往敵國和親重荠。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 前言 Redis緩存淘汰策略與Redis鍵的過期刪除策略并不完全相同虚茶,前者是在Redis內(nèi)存使用超過一定值的時候(...
    后廠村老司機閱讀 51,414評論 2 41
  • 發(fā)布訂閱模式 列表的局限 通過隊列的rpush 和lpop 可以實現(xiàn)消息隊列(隊尾進隊頭出)嘹叫,但是消費者需要不停地...
    WEIJAVA閱讀 552評論 0 1
  • 發(fā)布訂閱模式 列表的局限性 通過隊列的 rpush 和 lpop 可以實現(xiàn)消息隊列(隊尾進隊頭出)婆殿,但是消費者需要...
    vincent浩哥閱讀 232評論 0 0
  • Redis原理篇 1.發(fā)布 訂閱模式 1.1列表 的局限 ? 前面我們說通過隊列的 rpush 和 lpop ...
    Java小窩閱讀 347評論 0 0
  • 夜鶯2517閱讀 127,712評論 1 9