redis--內(nèi)存回收策略

[TOC]

1. Redis 被當(dāng)做緩存使用

當(dāng)Redis被當(dāng)做緩存來使用,當(dāng)你新增數(shù)據(jù)時妒蛇,讓它自動地回收舊數(shù)據(jù)是件很方便的事情机断。這個行為在開發(fā)者社區(qū)非常有名楷拳,因為它是流行的memcached系統(tǒng)的默認(rèn)行為绣夺。

LRU是Redis唯一支持的回收方法。

2. LRU算法

LRU是Least Recently Used的縮寫欢揖,即最近最少使用陶耍,是一種常用的頁面置換算法,選擇最近最久未使用的頁面予以淘汰她混。該算法賦予每個頁面一個訪問字段烈钞,用來記錄一個頁面自上次被訪問以來所經(jīng)歷的時間 t,當(dāng)須淘汰一個頁面時坤按,選擇現(xiàn)有頁面中其 t 值最大的毯欣,即最近最少使用的頁面予以淘汰。

----百度百科

主存容量遠(yuǎn)大于CPU緩存臭脓,磁盤容量遠(yuǎn)大于主存酗钞,因此無論是哪一層次的緩存都面臨一個同樣的問題:當(dāng)容量有限的緩存的空閑空間全部用完后,又有新的內(nèi)容需要添加進緩存時,如何挑選并舍棄原有的部分內(nèi)容砚作,從而騰出空間放入這些新的內(nèi)容窘奏。解決這個問題的算法有幾種,如最久未使用算法(LFU)葫录、先進先出算法(FIFO)着裹、最近最少使用算法(LRU)、非最近使用算法(NMRU)等米同,這些算法在不同層次的緩存上執(zhí)行時擁有不同的效率和代價骇扇,需根據(jù)具體場合選擇最合適的一種。

----維基百科

通俗理解就是哪個緩存最近被使用的最少面粮,就應(yīng)該丟棄匠题。

2.1 LRU算法

LRU(Least recently used,最近最少使用)算法根據(jù)數(shù)據(jù)的歷史訪問記錄來進行淘汰數(shù)據(jù)但金,其核心思想是“如果數(shù)據(jù)最近被訪問過韭山,那么將來被訪問的幾率也更高”。

一個緩存隊列冷溃。

  • 原理:

    1. 新數(shù)據(jù)放到隊列頭
    2. 每當(dāng)緩存被命中钱磅,將緩存移動到隊列頭
    3. 丟棄數(shù)據(jù)總是從隊列尾部開始
  • 命中率:

    當(dāng)存在批量的操作時,容易造成LRU命中率下降似枕,造成存儲污染盖淡。

    比如一直都是訪問1,2,3.如果有一個后臺任務(wù),將4,5,6掃描了一次凿歼,此時褪迟,如果需要丟棄,就會將熱點緩存丟棄答憔。造成緩存污染味赃。

  • 復(fù)雜度:簡單

  • 消耗:較高,命中需要遍歷隊列虐拓,命中需要做元素的轉(zhuǎn)移心俗。

img

2.2 LRU-K算法

在2.1中的LRU算法是,每當(dāng)緩存被命中蓉驹,就移動到頭部城榛。而LRU-K是指,當(dāng)緩存被命中K次時态兴,才會做元素的轉(zhuǎn)移狠持。

其核心思想是,命中一次可能不太可靠瞻润,需要命中指定的次數(shù)喘垂,才能被認(rèn)為是熱點緩存献汗。

相比LRU算法,LRU-K需要額外維護一個隊列==歷史訪問隊列==王污。

一個緩存隊列罢吃,一個緩存訪問歷史隊列。

  • 原理:

    1. 緩存數(shù)據(jù)第一次被命中昭齐,將命中次數(shù)++
    2. 當(dāng)命中次數(shù)達(dá)到K尿招,將緩存數(shù)據(jù)轉(zhuǎn)移到緩存隊列
    3. 丟棄數(shù)據(jù)總是從緩存隊列的尾部開始
    img
  • 命中率:因為LRU-K算法能在一定程度上去除突發(fā)或者批量操作的干擾,所以命中率比LRU算法要高阱驾。

  • 復(fù)雜度:多維護一個隊列就谜,需要額外的成本。

  • 消耗:LRU-K可以選擇即時轉(zhuǎn)移元素里覆,或者丟棄時轉(zhuǎn)移丧荐,在轉(zhuǎn)移的時候,有內(nèi)存消耗喧枷。

2.3 LRU-Two queues

LRU-Two queues類似LRU-2.區(qū)別在于將緩存訪問歷史隊列(不是緩存數(shù)據(jù)隊列)換成FIFO緩存隊列虹统。

所以LRU-T算法中,有兩個緩存隊列:FIFO緩存隊列和LRU緩存隊列隧甚。

緩存數(shù)據(jù)第一次被命中時车荔,放入FIFO緩存隊列;如果緩存數(shù)據(jù)第二次被命中戚扳,放入LRU緩存隊列忧便。

這兩個緩存隊列各自按照自己的緩存數(shù)據(jù)淘汰策略進行替換緩存。

  • 原理:
    1. 新訪問數(shù)據(jù)放入FIFO緩存隊列
    2. FIFO中的緩存數(shù)據(jù)被再次命中帽借,那么轉(zhuǎn)移到LRU緩存隊列中
    3. 如果LRU緩存隊列中的緩存數(shù)據(jù)被命中珠增,那么就將緩存數(shù)據(jù)轉(zhuǎn)移到LRU隊列頭部
    4. 丟棄數(shù)據(jù)從LRU或者FIFO隊列的尾部開始
  • 命中率:LRU-T算法的命中率高于LRU算法,在一定程度上也高于LRU-K算法砍艾。
  • 復(fù)雜度:兩個隊列蒂教,不過每個單個隊列都比較簡單
  • 消耗:FIFO和LRU消耗總和
img

2.4 Multi Queue

Multi Queue算法根據(jù)訪問頻率將數(shù)據(jù)劃分為多個隊列,不同的隊列具有不同的訪問優(yōu)先級辐董,其核心思想是:優(yōu)先緩存訪問次數(shù)多的數(shù)據(jù)悴品。
Multi Queue算法將緩存劃分為多個LRU隊列禀综,每個隊列對應(yīng)不同的訪問優(yōu)先級简烘。訪問優(yōu)先級是根據(jù)訪問次數(shù)計算出來的。

  • 原理:
    1. 新緩存數(shù)據(jù)在最低優(yōu)先級的隊列定枷,每個隊列按照LRU隊列管理
    2. 緩存命中次數(shù)達(dá)到一定的閾值孤澎,提升優(yōu)先級,進行隊列轉(zhuǎn)移
    3. 防止高優(yōu)先級累積效應(yīng)欠窒,在一定時間內(nèi)覆旭,高優(yōu)先級的緩存數(shù)據(jù)沒有被命中退子,需要做降級
    4. 緩存數(shù)據(jù)丟棄存在丟棄臨時隊列
    5. 丟棄數(shù)據(jù)從丟棄臨時隊列開始
  • 命中率:Multi Queue降低了“緩存污染”帶來的問題,命中率比LRU要高型将。
  • 復(fù)雜度:Multi Queue需要維護多個隊列寂祥,且需要維護每個數(shù)據(jù)的訪問時間,復(fù)雜度比LRU高七兜。
  • 消耗:Multi Queue需要記錄每個數(shù)據(jù)的訪問時間丸凭,需要定時掃描所有隊列,時間消耗比LRU要高腕铸∠空間上因為每個優(yōu)先級隊列的長度都很小,所以狠裹,空間消耗差不多虽界。
img

3. Maxmemory配置

maxmemory size用于配置Redis存儲數(shù)據(jù)時,指定限制的內(nèi)存大小涛菠。==此配置放在redis.conf中即可莉御。==

也可以使用CONFIG SET來運行時配置。

CONFIG SET命令用于在服務(wù)器運行期間重寫某些配置俗冻,而不用重啟Redis颈将。你可以使用此命令更改不重要的參數(shù)或從一個參數(shù)切換到另一個持久性選項。

可以通過CONFIG GET *獲得CONFIG SET命令支持的配置參數(shù)列表言疗,該命令是用于獲取有關(guān)正在運行的Redis實例的配置信息的對稱命令晴圾。

所有使用CONFIG SET設(shè)置的配置參數(shù)將會立即被Redis加載,并從下一個執(zhí)行的命令開始生效噪奄。

image-20200722142352545

設(shè)置maxmemory 0表示無內(nèi)存大小限制死姚,可以使用所有的內(nèi)存容量。

對于32位操作系統(tǒng)勤篮,默認(rèn)內(nèi)存限制3GB都毒。對于64位操作系統(tǒng),默認(rèn)內(nèi)存無限制碰缔。

4. 內(nèi)存回收策略

當(dāng)指定的內(nèi)存限制大小達(dá)到時账劲,需要選擇不同的行為,也就是策略金抡。

redis可以僅僅對命令返回錯誤瀑焦,這將導(dǎo)致內(nèi)存被使用的更多」8危或者回收一些舊的數(shù)據(jù)來使得添加數(shù)據(jù)時避免內(nèi)存限制榛瓮。

當(dāng)maxmemory限制達(dá)到的時候,redis使用的策略由maxmemory-policy配置指定巫击。

maxmemory-policy有以下待選:

  • noeviction: 返回錯誤禀晓。當(dāng)內(nèi)存限制達(dá)到精续,并且客戶端嘗試執(zhí)行更多內(nèi)存被使用的命令(一些刪除或者可能導(dǎo)致內(nèi)存占用減少的命令除外)
  • allkeys-lru:使用LRU算法。最少使用的緩存數(shù)據(jù)將被丟棄粹懒。
  • volatile-lru:類似使用LRU-K算法重付。擁有兩個隊列,一個是緩存隊列凫乖,一個是過期隊列堪夭,丟棄數(shù)據(jù)從過期隊列開始。
  • allkeys-random:隨機回收緩存數(shù)據(jù)拣凹。
  • volatile-random:隨機回收過期隊列的緩存數(shù)據(jù)森爽。
  • volatile-ttl:回收過期隊列的緩存數(shù)據(jù),而且優(yōu)先回收存活時間(ttl)較短的緩存數(shù)據(jù)嚣镜。

對于volatile前綴的策略爬迟,如果回收條件不滿足的話,那么和noeviction相同菊匿。

選擇正確的回收策略非常重要付呕,但是往往很多時候,策略的選擇需要大量的經(jīng)驗跌捆。

所以一開始可以根據(jù)這些特點選擇:

  • allkey-lru:請求符合冪定理分布徽职。即子集數(shù)據(jù)比其他數(shù)據(jù)訪問頻次更多∨搴瘢或者數(shù)據(jù)存在較為明顯的熱點分布的時候姆钉。
  • allkey-random:請求均勻分布,每個數(shù)據(jù)被訪問的頻次差不多抄瓦,沒有明顯區(qū)別潮瓶。
  • volatitle-ttl:數(shù)據(jù)有過期時間,或者大部分有過期時間钙姊。

過期時間的設(shè)置與維護毯辅,也是一個耗費資源的過程,所以使用allkeys-lru可能是更加高效的選擇煞额。

在配置了內(nèi)存回收策略后思恐,可以使用INFO命令查看瞬時redis服務(wù)器的資源消耗情況。

然后在分析redis資源使用情況膊毁,進行調(diào)整內(nèi)存回收策略胀莹。

5. 回收原理

原理:

  1. 客戶端執(zhí)行了新的命令,增加了新的數(shù)據(jù)媚媒,一塊內(nèi)存被占用
  2. redis在命令執(zhí)行完后嗜逻,檢查內(nèi)存使用情況,如果內(nèi)存限制超出maxmemory限制缭召,那么調(diào)用maxmemory-policy的策略進行回收

所以栈顷,設(shè)置了maxmemory并不是強制的,redis可能在很短的時間內(nèi)嵌巷,內(nèi)存占用超出了maxmemory的限制萄凤。redis的內(nèi)存占用不斷的穿越邊界值maxmemory,不斷的達(dá)到并超過邊界搪哪,然后又不斷的回收回到邊界以下靡努。

6. redis的LRU算法

redis的LRU算法,并不是標(biāo)準(zhǔn)的LRU算法晓折。

標(biāo)準(zhǔn)的LRU算法惑朦,需要將全部的緩存數(shù)據(jù)放到隊列中,這樣會消耗較多的內(nèi)存漓概。特別是對于redis經(jīng)常緩存億萬的數(shù)據(jù)來說漾月,將全部的key或者緩存數(shù)據(jù)放到隊列中,這幾乎是無法想象的災(zāi)難胃珍。

所以梁肿,在redis中使用標(biāo)準(zhǔn)的LRU算法是一種性能非常差的選擇,因此觅彰,在redis中使用的是近似的LRU算法吩蔑。

redis中近似的LRU算法與標(biāo)準(zhǔn)的LRU算法的區(qū)別在于:標(biāo)準(zhǔn)的LRU算法會將全部的數(shù)據(jù)進行統(tǒng)計;而redis近似的LRU算法則是隨機采樣填抬,隨機采樣指定個數(shù)的緩存數(shù)據(jù)烛芬,然后根據(jù)采樣結(jié)果,確定丟棄的緩存數(shù)據(jù)飒责。

==請注意蛀骇,這里的丟棄只是從內(nèi)存中丟棄,數(shù)據(jù)不會丟失读拆。類似我們硬盤上有16個G的數(shù)據(jù)擅憔,但是只有2G的內(nèi)存,那么需要計算機不斷的將新的數(shù)據(jù)從硬盤讀取檐晕,覆蓋舊的內(nèi)存數(shù)據(jù)暑诸。==

在redis.conf中有一個配置redis的LRU算法采樣數(shù)量的配置maxmemory-samples num,采樣數(shù)值越大,采樣范圍越大辟灰,得出的結(jié)論越準(zhǔn)確个榕。如果采樣是全體數(shù)據(jù),那么準(zhǔn)確率就是100%芥喇。不過采樣范圍的擴大西采,會導(dǎo)致整個采樣過程,需要消耗更多的資源继控。

maxmemory-samples也可以使用config set進行設(shè)置械馆。

這是redis官網(wǎng)的采樣測試結(jié)果:

[圖片上傳失敗...(image-16994-1596192689711)]

上面的圖片可以被分為4個小塊:第一個左上是標(biāo)準(zhǔn)LRU算法胖眷,第二個右上是采樣10次的redis近似LRU算法,第三個左下是采樣5次的結(jié)果,redis2.8霹崎,第四個右下是采樣5次的結(jié)果珊搀,redis3.0.

小圖是從上到下,從左到右創(chuàng)建尾菇,也就是左上角的小點是第一個境析,右下是最后一個。有時間順序派诬。

每一個小圖中劳淆,有三種顏色的小點組成:

  • 淺灰色:數(shù)據(jù)被回收
  • 深灰色:數(shù)據(jù)沒有被回收
  • 深綠色:數(shù)據(jù)新建

當(dāng)采樣次數(shù)為5時苞轿,redis3.0好于redis2.8.在第三個中端仰,存在大量的深灰色小點,而且分布沒有明顯的界限小渊,即使很多很早時間創(chuàng)建放可,也沒有被回收谒臼。

在第四個圖找那個,我們可以明顯的看到灰色區(qū)域有較為明顯的分割帶耀里,不過深灰色色帶所占比例不是很多蜈缤,還不是非常理想。

對于都redis3.0比較冯挎,第二個灰色之間有更加明顯的分隔帶底哥,而且色帶分布比例均勻,差不多是50%.

與標(biāo)準(zhǔn)的LRU算法結(jié)果比較房官,采樣次數(shù)高趾徽,redis版本新,算法更接近標(biāo)準(zhǔn)LRU翰守。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末孵奶,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蜡峰,更是在濱河造成了極大的恐慌了袁,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件湿颅,死亡現(xiàn)場離奇詭異载绿,居然都是意外死亡,警方通過查閱死者的電腦和手機油航,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門崭庸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事怕享≈瓷模” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵熬粗,是天一觀的道長搀玖。 經(jīng)常有香客問我余境,道長驻呐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任芳来,我火速辦了婚禮含末,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘即舌。我一直安慰自己佣盒,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布顽聂。 她就那樣靜靜地躺著肥惭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪紊搪。 梳的紋絲不亂的頭發(fā)上蜜葱,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音耀石,去河邊找鬼牵囤。 笑死,一個胖子當(dāng)著我的面吹牛滞伟,可吹牛的內(nèi)容都是我干的揭鳞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼梆奈,長吁一口氣:“原來是場噩夢啊……” “哼野崇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起亩钟,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤乓梨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后径荔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體督禽,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年总处,在試婚紗的時候發(fā)現(xiàn)自己被綠了狈惫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖胧谈,靈堂內(nèi)的尸體忽然破棺而出忆肾,到底是詐尸還是另有隱情,我是刑警寧澤菱肖,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布客冈,位于F島的核電站,受9級特大地震影響稳强,放射性物質(zhì)發(fā)生泄漏场仲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一退疫、第九天 我趴在偏房一處隱蔽的房頂上張望渠缕。 院中可真熱鬧,春花似錦褒繁、人聲如沸亦鳞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽燕差。三九已至,卻和暖如春坝冕,著一層夾襖步出監(jiān)牢的瞬間徒探,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工徽诲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留刹帕,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓谎替,卻偏偏與公主長得像偷溺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子钱贯,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355