Redis 內(nèi)存滿了怎么辦?這樣設(shè)置才正確!
上回在《??Redis 數(shù)據(jù)過(guò)期了會(huì)被立馬刪除么???》說(shuō)到如果過(guò)期的數(shù)據(jù)太多,定時(shí)刪除無(wú)法刪除完全(每次刪除完過(guò)期的 key 還是超過(guò) 25%),同時(shí)這些 key 再也不會(huì)被客戶端請(qǐng)求,就無(wú)法走惰性刪除,內(nèi)存被打滿會(huì)怎樣?
答案是走內(nèi)存淘汰機(jī)制。
故事從一個(gè)叫 Redis 帝國(guó)的三公九卿官職說(shuō)起……
在 Redis 帝國(guó)中,整個(gè)帝國(guó)的國(guó)法、家法和軍法等都記錄在 redis.conf中,它控制著整個(gè)帝國(guó)的運(yùn)行。
公務(wù)員占用的國(guó)家地盤(pán)資源大小限定由名叫「maxmemory」的司法官員制定,一共有兩種方式實(shí)現(xiàn):
- 在運(yùn)行時(shí)使用 CONFIG SET maxmemory 4gb指定帝國(guó)官職人員最大地盤(pán)資源為 4GB;
- 將 maxmemory 4gb法令記錄到 redis.conf「法典」中,在帝國(guó)運(yùn)轉(zhuǎn)指定使用該「法典」運(yùn)行。
需要注意的是,如果 maxmemory 為 0 ,在 64 位「空間」上則沒(méi)有限制,而 32 位「空間」則有 3GB 的隱式限制。
Redis 內(nèi)存淘汰策略
設(shè)置了帝國(guó)官職地盤(pán)資源限制,每年選拔新人就會(huì)導(dǎo)致沒(méi)有地盤(pán)資源可以使用怎么辦?如何選擇一些公務(wù)員淘汰?
在 Redis 4.0 時(shí)代,一共有 6 種淘汰策略,之后,又新增了 2 種策略。
總體上我們可以根據(jù)是否需要淘汰可以分為兩大類(lèi):
- 不執(zhí)行淘汰策略,noeviction;
- 根據(jù)不同法則淘汰的其他 7 種策略。
noeviction 不退伍策略
默認(rèn)情況下,資源超過(guò) maxmemory 的值也不會(huì)執(zhí)行淘汰,不允許新人加入。
關(guān)系戶啊這是,皇親國(guó)戚,永久 vip 啊喂。
隨著官職人員的新增,由于不會(huì)淘汰,資源容量遲早會(huì)滿。滿了以后,當(dāng)有「新人」想要進(jìn)來(lái)的時(shí)候,Redis 直接返回錯(cuò)誤,并罷工。
秀,真是任性。
各式各樣的淘汰策略
剩下的 7 種策略還可以根據(jù)淘汰的候選集合和淘汰范圍分為兩大類(lèi):
- 對(duì)有設(shè)置任職過(guò)期時(shí)間的職員進(jìn)行淘汰,沒(méi)有設(shè)定任職過(guò)期時(shí)間的不會(huì)淘汰,淘汰策略如下:
volatile-lru:淘汰最近最少上一線干活的人員;
volatile-lfu:4.0 之后新增的策略,淘汰上一線干活次數(shù)最少的人員;
volatile-random:隨機(jī)淘汰,騰出坑位給新人;
volatile-ttl:淘汰設(shè)置了任期時(shí)間的公務(wù)員,誰(shuí)最接近任期時(shí)間就先淘汰誰(shuí)。
- 對(duì)所有類(lèi)型人員淘汰,不管是永久 vip 的皇親國(guó)戚還是設(shè)置了任職過(guò)期時(shí)間的人員。
allkeys-lru:淘汰最近最少上一線干活的職員;
allkeys-lfu:淘汰最少上一線干活的公務(wù)員;
allkeys-random:隨機(jī)淘汰職員,為新兵騰出空位。
故事到這里就結(jié)束了,接下來(lái)「碼哥」分享下在實(shí)際 Redis 中如何選擇合適的淘汰策略和設(shè)置最佳緩存大小給大家。
淘汰執(zhí)行過(guò)程如下圖所示:

redis-eviction
- 客戶端發(fā)送新命令到服務(wù)端;
- 服務(wù)端收到客戶端命令,Redis 檢查內(nèi)存使用情況,如果大于 maxmemory 限制,則根據(jù)策略驅(qū)逐數(shù)據(jù)。
- 執(zhí)行新命令。
allkeys-lru 使用場(chǎng)景
假如你的應(yīng)用存在明顯的冷熱數(shù)據(jù)區(qū)別,根據(jù)經(jīng)驗(yàn)推薦你使用這個(gè)策略,充分利用 LRU 算法把最近最常訪問(wèn)的數(shù)據(jù)保留,有限的內(nèi)存提高訪問(wèn)性能。
allkeys-random 使用場(chǎng)景
假如數(shù)據(jù)沒(méi)有明顯的冷熱分別,所有的數(shù)據(jù)分布查詢(xún)比較均衡,這些數(shù)據(jù)都會(huì)被隨機(jī)查詢(xún),那就使用 allkeys-random 策略,讓其隨機(jī)選擇淘汰數(shù)據(jù)。
volatile-lru 使用場(chǎng)景
業(yè)務(wù)場(chǎng)景有一些數(shù)據(jù)不能刪除,比如置頂新聞、視頻,這時(shí)候我們?yōu)檫@些數(shù)據(jù)不設(shè)置過(guò)期時(shí)間,這樣的話數(shù)據(jù)就不會(huì)被刪除,該策略就會(huì)去根據(jù) LRU 算法去淘汰那些設(shè)置了過(guò)期時(shí)間且最近最少被訪問(wèn)的數(shù)據(jù)。
有一個(gè)點(diǎn)需要注意下,為 key 執(zhí)行 expire 設(shè)置過(guò)期時(shí)間會(huì)消耗一些內(nèi)存,所以使用 allkeyds-lru 會(huì)提高內(nèi)存效率。
將需要持?jǐn)?shù)據(jù)不能刪除的和全都可以淘汰數(shù)據(jù)的業(yè)務(wù)系統(tǒng)分別使用不同的 Redis 實(shí)例集群是更好的方案。
針對(duì)業(yè)務(wù)場(chǎng)景有一些數(shù)據(jù)不能刪除的使用 volatile-lru策略,另一類(lèi)則可以使用 allkyes-lru 或者 allkeys-random。
Redis 容量設(shè)置多大合適
緩存并不是越大越好,用最小的代價(jià)去獲得最高的收益才是老板想要的。
數(shù)據(jù)訪問(wèn)有局部性,根據(jù)「二八原理」:通常 20% 的數(shù)據(jù)能支撐 80% 的訪問(wèn)請(qǐng)求。
所以我們可不可以把緩存容量大小設(shè)置為總數(shù)據(jù)量的 20%?
當(dāng)然,不能這么絕對(duì),這是理想狀態(tài)。因?yàn)榭赡艽嬖谝恍﹤€(gè)性化需求,不同的用戶訪問(wèn)的數(shù)據(jù)可能差別很大,不完全具備「二八原理」。
我們應(yīng)當(dāng)結(jié)合實(shí)際的訪問(wèn)特點(diǎn)和成本來(lái)綜合評(píng)估。根據(jù)經(jīng)驗(yàn)建議將容量設(shè)置成總數(shù)據(jù)量的 15%~30%。
碼哥,其他淘汰規(guī)則比較簡(jiǎn)單,volatile-lru 和 volatile-lfu 則比較復(fù)雜,他們的算法是怎樣的?
volatile-lru 使用了 LRU 算法,淘汰最近最少使用的數(shù)據(jù)。而 volatile-lfu 使用了 LFU 算法,它在 LRU 算法基礎(chǔ)上同時(shí)考慮了數(shù)據(jù)的時(shí)效性和訪問(wèn)頻率,最少訪問(wèn)的 key 會(huì)被刪除。
至于具體算法細(xì)節(jié),我們下回分解。一次性太多的話大家容易在知識(shí)的海洋里里嗆水。






























