目錄
- 一、Redis最大記憶體
- 1.1 預估最大記憶體
- 1.2 設定最大記憶體
- 二、記憶體淘汰策略
- 2.1 洗掉過期鍵物件
- 2.2 記憶體溢位控制策略
- 三、記憶體淘汰流程以及影響
一、Redis最大記憶體
1.1 預估最大記憶體
Redis作為記憶體資料庫,需要盡量把那些頻繁被訪問的熱點資料放入Redis,
按照二八原則,20%的資料承載了80%的訪問量,可以按照這個原則來預估實際的Redis記憶體大小,比如后臺資料庫的容量是10GB,那么Redis的容量可以設定為2GB,
二八原則是個常規的估算,有些具體情況還要具體對待:
- 比如針對電商的促銷,可能熱點資料只占全部全部商品資料的10%,
- 針對有個性化推薦的內容,20%的資料可能無法提供80%的訪問量,可能需要40-50%的資料才行
- 還有一些場景,為了最大的性能,也有可能100%的資料全部放入redis,比如秒殺場景,可以把所有參與秒殺的商品資料全部放入redis,
確定了最大記憶體后就可以設定redis的最大記憶體,
1.2 設定最大記憶體
redis默認無限使用服務器記憶體,為了防止在極端情況下服務器記憶體被耗盡,redis需要設定最大記憶體,
使用命令
src/redis-cli config set maxmemory 4gb
maxmemory僅僅是指redis資料實際占用的記憶體(自身,資料,緩沖區),不包含碎片,
二、記憶體淘汰策略
2.1 洗掉過期鍵物件
惰性洗掉
惰性洗掉是在在客戶端訪問的時候check一下資料是否過期,如果過期則立即洗掉,不給客戶端回傳任何值,惰性洗掉可以降低洗掉對CPU的影響,但是如果一個key一直不被訪問,那么這個key就有可能一直不會過期,最侄訓造成資料的浪費, 所以引入了定時任務洗掉,
定時任務洗掉
Redis內部維護的定時任務,執行流程:

- 隨機選擇20個key
- .如果過期的key的數量大于25%,則回圈執行過期key洗掉
- 洗掉程序中如果發現超時(25毫秒),則進入快速回收模式:
- 洗掉的超時時間設為1毫秒
- 2 秒內只執行一次
定時任務的執行頻率由hz引數控制,默認為10,表述一秒執行10次,
惰性任務和定時任務都有一定的隨機性,最侄訓是有key一直執行不到,但是已經過期,這些key永遠都不會被淘汰,所以redis還引入了相對比較精準的淘汰策略,
2.2 記憶體溢位控制策略

該值由下面引數控制,
maxmemory-policy
不淘汰策略
noeviction是redis的默認策略,當記憶體使用超過配置的時候會回傳錯誤,不會洗掉任何鍵,如果有寫請求進來,redis直接報錯,不提供服務,但是讀請求可以照常執行,
淘汰策略
基于過期時間key的淘汰策略:
1. volatile-lru:對于設定了過期時間的key,淘汰最久沒有使用的key(LRU演算法)
2. volatile-randow:對于設定了過期時間的key,隨機選擇key進行淘汰
3. volatile-ttl:對于設定了過期時間的key,淘汰過期時間最早的key
4. volatile-lfu:對于設定了過期時間的key,淘汰但使用頻率最少的鍵(LFU演算法)
所有key的淘汰策略:
1. volatile-lru:對于所有key,淘汰久沒有使用的key(LRU演算法)
2. volatile-randow:對于所有key,隨機選擇key進行淘汰
3. volatile-lfu:對于所有key,淘汰使用頻率最少的鍵(LFU演算法)
LRU( Least Recently Used)
按照最少使用原則進行資料篩選,最不常用的資料會被選中,頻繁使用的資料會持續保留,
LRU會把所有資料組裝成一個鏈表,表頭代表最近使用的資料,表位表示最久沒有使用的資料,用于淘汰,

- 新加入的資料放入表頭
- 資料被訪問后移到表頭,
- 淘汰表尾
LRU的核心是要維護一個鏈表,對于有大量key的redis來說,太重了,鏈表的維護會影響redis的性能,
Redis對LRU做個改造:
-
RedisObject會記錄每個物件的lru,
-
當有資料會淘汰時,redis會隨機選擇N個資料,作為一個集合,
-
針對這N個資料,redis會對比起lru,把lru最小的資料淘汰,
-
N的值redis提供了配置
maxmemory-samples默認值為5,當配置為10時,改造的lru接近正式的lru,但是比較耗費cpu,建議保持默認即可,
-
當需要再次淘汰資料時,選擇lru小于 < min(第一次初始化的集合的lru) 的資料進入集合,然后再基于lru進行淘汰,
配置建議:
- 優先allkeys-lru:充分使用lru演算法,尤其當資料冷熱比較明顯時,最大限度的保證熱點資料補被淘汰,
- 沒有明顯的冷熱,可以選擇allkeys-random,隨機過期即可,
- 如果資料有長期不過期的資料,這些資料可以不設定過期時間,建議使用voliate-lru,這樣沒有過期時間的資料不會被淘汰,而其他資料可以享受lru演算法進行淘汰,
三、記憶體淘汰流程以及影響
如果設定了maxmemory,redis在每次執行任務時候都會嘗試記憶體回收,當redis一直作業在記憶體溢位狀態(used_memory > maxmemory)下,且不是noeviction策略時,會頻繁的觸發回收記憶體的操作,影響redis的性能,
頻繁回收記憶體成本很高:
- 查找可以回收的key
- 洗掉key
- 主從模式下,將洗掉命令slave,
流程

建議在生產環境redis的作業在maxmemory > used_memory的狀態下,盡量避免頻繁的記憶體回收開銷,
[官網參考]https://redis.io/topics/lru-cache
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/256277.html
標籤:NoSQL
上一篇:Mongo 創建索引
