面試官問:Redis緩存淘汰策略有哪些?
我們知道:Redis是基于內存的,面試官問:
- 生產環(huán)境Redis內存如何分配?
- Redis鍵過期了如何刪除?
- ......
圖片
本小節(jié)不僅適用于工作,也是面試的高頻問題。
文章導讀
圖片
Redis內存分析
一、Redis默認內存是多少?
在 64bit 系統(tǒng)下,默認不限制內存大小,不設置內存大小和maxmemory = 0表示不限制 Redis 內存使用
二、如何查看Redis最大內存是多少?
- 命令行
127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "0"
- 配置文件 redis.conf
# maxmemory <bytes>
三、如何查看Redis內存使用情況?
127.0.0.1:6379> info memory
四、如何配置和修改?
- 臨時方案,通過命令修改
127.0.0.1:6379> config set maxmemory 104857600
OK
127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "104857600"
- 永久方案,通過配置文件
圖片
五、生產環(huán)境如何配置?
建議:一般取物理內存的3/4
Redis過期鍵刪除?
我們知道,redis一般會設置過期時間。那么這些鍵過期了是立刻從內存中刪除嗎?
通常,鍵刪除會有不同的策略
一、立刻刪除
立即刪除能保證過期鍵值會在過期后馬上被刪除,其所占用的內存也會隨之釋放。但是刪除操作會占用cpu的時間,造成CPU額外的壓力。
redis.conf 中,通過調整過期鍵的檢測頻率
# The range is between 1 and 500, however a value over 100 is usually not
# a good idea. Most users should use the default of 10 and raise this up to
# 100 only in environments where very low latency is required.
hz 10
但是這會產生大量的性能消耗,同時也會影響數(shù)據的讀取操作。
二、惰性刪除
數(shù)據到達過期時間,不做處理。等下次訪問該數(shù)據時,
- 如果未過期,返回數(shù)據 ;
- 發(fā)現(xiàn)已過期,刪除,返回不存在。
惰性刪除策略的缺點是,它對內存是最不友好的。如果一個鍵已經過期,而這個鍵又仍然保留在redis中,那么只要這個過期鍵不被刪除,它所占用的內存就不會釋放。
#開啟憜性淘汰
lazyfree-lazy-evictinotallow=yes
三、定期刪除
這種方案有效規(guī)避上述兩種極端情況, 定期刪除策略的難點是確定刪除操作執(zhí)行的時長和頻率:
- 如果刪除操作執(zhí)行得太頻繁或者執(zhí)行的時間太長,定期刪除策略就會退化成立即刪除策略。
- 如果刪除操作執(zhí)行得太少,或者執(zhí)行的時間太短,定期刪除策略又會和惰性刪除束略一樣,出現(xiàn)浪費內存的情況。
- 因此,如果采用定期刪除策略的話,服務器必須根據情況,合理地設置刪除操作的執(zhí)行時長和執(zhí)行頻率。
Redis內存淘汰策略
基于上述的了解,假如:
1 定期刪除時,從來沒有被抽查到
2 惰性刪除時,也從來沒有被點中使用過
上述兩個步驟,依然會有大量過期的key堆積在內存中,導致redis內存空間緊張或者很快耗盡。
因此,有沒有一個更好的兜底方案......?這就是要講的淘汰策略
一、LRU和LFU區(qū)別?
LRU(Least Recently Used,最近最少使用頁面置換算法)
假設我們有一個容量為3的LRU緩存,訪問數(shù)據的順序如下:
- 訪問數(shù)據1,緩存中現(xiàn)在有:[1]
- 訪問數(shù)據2,緩存中現(xiàn)在有:[1, 2]
- 訪問數(shù)據3,緩存中現(xiàn)在有:[1, 2, 3]
- 再次訪問數(shù)據1,緩存中現(xiàn)在有:[2, 3, 1](因為1被重新訪問,它被移到了列表的末尾)
- 訪問數(shù)據4,由于緩存已滿,最不常用的數(shù)據2將被淘汰,緩存中現(xiàn)在有:[3, 1, 4]
原理:如果數(shù)據最近被訪問過,那么在不久的將來它很可能再次被訪問。因此,LRU會淘汰最長時間未被訪問的數(shù)據。
適用場景:適用于最近被訪問的數(shù)據在未來某個時間點很可能再次被訪問。
LFU(Least Frequently Used,最近最不常用頁面置換算法)
假設我們有一個容量為3的LFU緩存,訪問數(shù)據的順序如下:
- 訪問數(shù)據1,計數(shù)器:{1: 1}
- 訪問數(shù)據2,計數(shù)器:{1: 1, 2: 1}
- 訪問數(shù)據1,計數(shù)器:{1: 2, 2: 1}
- 訪問數(shù)據3,計數(shù)器:{1: 2, 2: 1, 3: 1}
- 訪問數(shù)據1,計數(shù)器:{1: 3, 2: 1, 3: 1}
- 訪問數(shù)據4,由于緩存已滿,訪問次數(shù)最少的數(shù)據2將被淘汰,計數(shù)器:{1: 3, 3: 1, 4: 1}
原理:LFU算法會跟蹤每個頁面在特定時間段內被訪問的頻率。當需要淘汰頁面時,LFU算法會淘汰在該時間段內訪問次數(shù)最少的頁面。
適用場景:LFU算法適用于那些訪問模式可能隨時間變化的場景,或者訪問頻率能夠較好地反映頁面重要性的情況。
小結
- LRU關注數(shù)據的最近訪問時間,淘汰最長時間未被訪問的數(shù)據。
- LFU關注數(shù)據的訪問頻率,淘汰訪問次數(shù)最少的數(shù)據。
二、Redis有哪些淘汰策略?
redis.config 配置文件中,
# volatile-lru -> Evict using approximated LRU, only keys with an expire set.
# allkeys-lru -> Evict any key using approximated LRU.
# volatile-lfu -> Evict using approximated LFU, only keys with an expire set.
# allkeys-lfu -> Evict any key using approximated LFU.
# volatile-random -> Remove a random key having an expire set.
# allkeys-random -> Remove a random key, any key.
# volatile-ttl -> Remove the key with the nearest expire time (minor TTL)
# noeviction -> Don't evict anything, just return an error on write operations.
解釋下:
volatile-lru:使用近似的最近最少使用(LRU)算法淘汰鍵。但是,只有那些設置了過期時間的鍵(即“volatile”鍵)才會被考慮淘汰。
allkeys-lru:使用近似的LRU算法淘汰任何鍵,無論它們是否設置了過期時間。
volatile-lfu:使用近似的最少頻率使用(LFU)算法淘汰鍵。同樣,只有設置了過期時間的鍵會被考慮。
allkeys-lfu:使用近似的LFU算法淘汰任何鍵,不考慮它們是否設置了過期時間。
volatile-random:隨機淘汰一個設置了過期時間的鍵。
allkeys-random:隨機淘汰任何鍵,不論它們是否設置了過期時間。
volatile-ttl:淘汰具有最短剩余生存時間(TTL)的鍵,即那些最接近過期時間的鍵。
noeviction:不淘汰任何鍵。當內存達到最大容量時,Redis將不會進行任何淘汰操作,而是在寫入新數(shù)據時返回錯誤。
三、生產如何選擇淘汰策略?
在生產環(huán)境中選擇緩存淘汰策略時,通常需要根據應用的具體需求和數(shù)據特性來定。這里給出常見案例:
電商平臺的商品推薦
電商平臺需要為用戶展示個性化的商品推薦,其中熱門商品的訪問頻率較高。可選擇:LFU(Least Frequently Used)
redis-cli config set maxmemory-policy allkeys-lfu
因為LFU策略可以保留訪問頻率高的商品,確保推薦列表中展示用戶最可能感興趣的商品。
金融交易平臺的實時數(shù)據
金融交易平臺需要提供實時的股票價格和交易數(shù)據,數(shù)據的實時性至關重要。過期的時價被淘汰。
可選擇:TTL(Time To Live)結合LRU(Least Recently Used)
redis-cli config set maxmemory-policy volatile-lru
TTL確保數(shù)據在一定時間后自動過期,而LRU保證最近訪問的數(shù)據被優(yōu)先保留。
電信運營商的用戶數(shù)據管理
電信運營商需要處理和緩存大量用戶的通話記錄、短信記錄等,用戶通常更關心最近的通信記錄。
可選擇:LRU(Least Recently Used)
redis-cli config set maxmemory-policy allkeys-lru
因為LRU策略可以確保最近生成的通話記錄和短信記錄被優(yōu)先緩存。
社交媒體平臺的用戶動態(tài)
社交媒體平臺需要為用戶展示好友的最新動態(tài)和帖子,用戶通常對最新動態(tài)感興趣。
可選擇:LRU
redis-cli config set maxmemory-policy allkeys-lru
因為LRU可以保證最新的帖子被優(yōu)先展示。
好了,今天就聊到這里,讀者可依據實際情況擇優(yōu)選擇策略。