Redis作為當前最常用的開源內存數據庫,性能十分高,據官方數據表示Redis讀的速度是110000次/s,寫的速度是81000次/s 。而且Redis支持數據持久化,眾多數據結構存儲,master-slave模式數據備份等多種功能。
但是長期將Redis作為緩存使用,難免會遇到內存空間存儲瓶頸,當Redis內存超出物理內存限制時,內存數據就會與磁盤產生頻繁交換,使Redis性能急劇下降。此時如何淘汰無用數據釋放空間,存儲新數據就變得尤為重要了。
對此,Redis在生產環境中,采用配置參數maxmemory 的方式來限制內存大小。當實際存儲內存超出maxmemory 參數值時,開發者們可以通過這幾種方法——Redis內存淘汰策略,來決定如何騰出新空間繼續支持讀寫工作。
那么Redis內存淘汰策略是如何工作的呢?
首先,客戶端會發起需要更多內存的申請;
其次,Redis檢查內存使用情況,如果實際使用內存已經超出maxmemory,Redis就會根據用戶配置的淘汰策略選出無用的key;
最后,確認選中數據沒有問題,成功執行淘汰任務。
當前Redis3.0版本支持的淘汰策略有6種:
1. volatile-lru:從設置過期時間的數據集(server.db[i].expires)中挑選出最近最少使用的數據淘汰。沒有設置過期時間的key不會被淘汰,這樣就可以在增加內存空間的同時保證需要持久化的數據不會丟失。
2. volatile-ttl:除了淘汰機制采用LRU,策略基本上與volatile-lru相似,從設置過期時間的數據集(server.db[i].expires)中挑選將要過期的數據淘汰,ttl值越小越優先被淘汰。
3. volatile-random:從已設置過期時間的數據集(server.db[i].expires)中任意選擇數據淘汰。當內存達到限制無法寫入非過期時間的數據集時,可以通過該淘汰策略在主鍵空間中隨機移除某個key。
4. allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰,該策略要淘汰的key面向的是全體key集合,而非過期的key集合。
5. allkeys-random:從數據集(server.db[i].dict)中選擇任意數據淘汰。
6. no-enviction:禁止驅逐數據,也就是當內存不足以容納新入數據時,新寫入操作就會報錯,請求可以繼續進行,線上任務也不能持續進行,采用no-enviction策略可以保證數據不被丟失,這也是系統默認的一種淘汰策略。
上述是Redis的6種淘汰策略,關於使用這6種策略,開發者還需要根據自身系統特征,正確選擇或修改驅逐。
1. 在Redis中,數據有一部分訪問頻率較高,其余部分訪問頻率較低,或者無法預測數據的使用頻率時,設置allkeys-lru是比較合適的。
2. 如果所有數據訪問概率大致相等時,可以選擇allkeys-random。
3. 如果研發者需要通過設置不同的ttl來判斷數據過期的先后順序,此時可以選擇volatile-ttl策略。
4. 如果希望一些數據能長期被保存,而一些數據可以被淘汰掉時,選擇volatile-lru或volatile-random都是比較不錯的。
5. 由於設置expire會消耗額外的內存,如果計划避免Redis內存在此項上的浪費,可以選用allkeys-lru 策略,這樣就可以不再設置過期時間,高效利用內存了。
Redis緩存功能,是由edis.c文件中的freeMemoryIfNeeded函數實現的。如果maxmemory被設置,那么每次在執行命令錢,該函數都會被調用來判斷內存是否夠用、釋放內存、返回錯誤。如果沒有足夠的內存程序主邏輯將會阻止設置了REDIS_COM_DENYOOM flag的命令執行,對其返回command not allowed when used memory > ‘maxmemory’的錯誤消息。
作者:Titan框架
鏈接:https://www.jianshu.com/p/b1b4eeccc140
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。