什么是內存回收機制?
眾所周知Redis之所以性能高是因為數據都存在內存中,內存是很寶貴的,Redis的內存回收機制本質就是處理達到過期時間的key-value,以及當內存到達最大使用值時候觸發的內存淘汰策略。
Redis數據刪除的策略有哪些?
定時過期(主動淘汰):創建一個定時器,當key設置有過期時間,且達到過期時間的時候,由定時器任務立即執行刪除操作。
- 優點:節約內存,到期就刪除,快速釋放不需要的內存占用。
- 缺點:cpu壓力很大,無論此時cpu負載多高,均占用cpu資源,會影響redis服務器響應時間和吞吐量。
- 總結:用處理器性能換存儲空間(時間換空間)。
惰性刪除(被動淘汰):數據到達過期時間,不做處理,等下次訪問該數據時,如果過期就刪除,不返回數據,否則正常返回。
- 優點:節約cpu性能,發現必須刪除時候才刪除。
- 缺點:內存壓力大,無效數據長期占用內存空間,存在內存泄漏的風險。
- 總結:用內存存儲空間換處理器性能。
定時過期(主動淘汰):創建一個定時器,當key設置有過期時間,且達到過期時間的時候,由定時器任務立即執行刪除操作。
- 優點:節約cpu性能,發現必須刪除時候才刪除。
- 缺點:不好確定刪除操作執行時長和頻率,執行太頻繁,CPU壓力大,執行間隔太久,和惰性刪除一樣,存在返回錯誤數據的風險,比如某個key已經到了過期時間,但是還沒有執行定期刪除,業務查無的時候會返回該數據,該數據是錯誤數據。
- 總結:周期性抽查存儲空間,通過調整定時掃描的時間間隔和每次掃描的限定耗時,盡量達到CPU和內存資源平衡效果,一般不推薦使用。
Redis采用的是定時刪除和惰性刪除的機制實現過期鍵的內存回收。
Redis對于設置了過期時間的key的逐出算法有哪些?
- volatile-lru:對生存周期內最少有使用key進行置換(強調的是距離當前的時間,僅關注數據訪問時間和順序,忽略訪問次數)。
- volatile-lfu:對生存周期內最少使用次數key進行置換(強調的是時間周期內的使用次數,關注時間區間內數據訪問次數)。
- volatile-random:對生存周期中的key進行隨機置換。
- volatile-ttl:挑選將要過期的數據進行淘汰。
Redis對于全庫的key的逐出算法有哪些?
- allkeys-lru:挑選最近最少使用的數據淘汰(強調的是距離當前的時間,僅關注數據訪問時間和順序,忽略訪問次數)。
- allkeys-lfu:挑選最近使用次數最少的數據淘汰(強調的是時間周期內的使用次數,關注時間區間內數據訪問次數)。
- allkeys-random:隨機選擇數據淘汰。
Redis默認的逐出策略是noeviction,當內存使用達到閾值的時候,所有申請內存的命令會報OOM。
LRU算法和LFU算法:
- LRU算法:LRU(Least Recently Used)最近最少使用(最長時間不被使用)淘汰算法,LRU算法是淘汰最長時間沒有使用key。
- LFU算法:LFU(Least Frequently Used)最不經常使用(使用次數最少)淘汰算法,LFU是淘汰一段時間內,使用次數最少的key。
Reidis 碎片及原因?
內存分配器的分配策略決定操作系統無法按需分配,這是因為內存分配器一般是按固定大小來分配內存,而不是完全按照應用程序申請的內存空間大小給程序分配,Redis按照固定的大小將空間分配為例如8字節 16字節 32 字節 等等,Redis這么做的目的是減少分配次數,提高性能,比如客戶端申請一個20字節的空間,Redis會分配一個32字節的空間,如果后面在追加10個字節的數據,Redis就無需再次分配空間了。而Redis內存碎片的產生也是因為這個策略,同樣如客戶端申請一個20字節的空間,Redis會分配一個32字節的空間,后續不在增加數據了,就浪費了12字節的空間,這就是內存碎片。
可以使用 info memory 查詢內存的使用詳細信息,mem_fragmentation_ratio 大于1.5表示內存碎片嚴重,需要處理了。
如何解決Redis的內存碎片問題?
- 重啟Redis,數據重建,內存碎片問題會得到大大改善,線上一般不允許這么操作。
- 開啟內存碎片自動清理,
config set activedefrag yes;#表示內存碎片的字節數達到 100MB 時,開始清理;active-defrag-ignore-bytes 100mb;#表示內存碎片空間占操作系統分配給 Redis 的總空間比例達到 10% 時,開始清理active-defrag-threshold-lower 10;
如有不正確的地方請各位指出糾正。