? ? ? Redis是基于內存存儲的,非關系型,鍵值對數據庫。因此,對Redis來說,內存空間的管理至關重要。那Redis是如何內存管理的呢?
一、最大內存限制
? ? ?Redis 提供了 maxmemory?參數允許用戶設置 Redis 可以使用的最大內存大小。當 Redis 使用的內存量達到 maxmemory?設置的上限時,Redis 會根據配置的淘汰策略(如 LRU、LFU、TTL 等)自動刪除某些鍵值對以釋放內存。
二、過期鍵刪除策略
? ? ?用戶可以為鍵設置過期時間,當鍵過期后,Redis 采用多種方式處理:
? ? ?1、定期刪除:Redis 會周期性地隨機檢查并刪除一部分已過期的鍵。
? ? ?2、惰性刪除:在訪問某個鍵時,如果發現該鍵已過期,則立即刪除它。
? ? ?3、主動淘汰:結合上述兩種方法,在內存不足時按照特定策略主動淘汰未過期的鍵。
三、內存分配與回收
? ? ?Redis 使用jemalloc或libc等高效的內存分配器進行內部數據結構(如字符串、哈希表、鏈表、集合等)的內存分配與回收,減少內存碎片。
四、結合數據結構和編碼方式做內存優化
? ? ?Redis 的內部數據結構經過特殊設計,能夠緊湊存儲不同類型的數據,例如簡單動態字符串SDS、壓縮列表ziplist等。
? ? ?Redis 還支持多種編碼方式,針對不同場景下的數據量和訪問模式選擇最節省空間的編碼方式,如哈希表的ziplist編碼和hashtable編碼切換。
五、內存淘汰策略
? ? ?當達到內存上限且有新數據需要插入時,Redis 會按照預設的淘汰策略從數據集中選擇合適的鍵刪除,常見的淘汰策略包括:
? ? ? noeviction:不刪除任何數據,返回錯誤給客戶端(當內存達到 maxmemory 時不再執行寫操作)。
? ? ?volatile-lru/volatile-ttl/allkeys-lru/allkeys-random/allkeys-lfu:基于 LRU(最近最少使用)、TTL(過期時間)、LFU(最不經常使用)或隨機選擇鍵進行刪除。
? ? ?在java中,我們了解過jvm的垃圾回收機制對未被引用的對象進行回收的過程。那在Redis中,是如何被回收呢?
答:在 Redis 中,內存管理采用了引用計數(Reference Counting)的方式來跟蹤對象的生命周期。這意味著每個 Redis 對象都有一個引用計數器,當有新的引用指向該對象時,引用計數加1;當引用移除時,引用計數減1。
? ? ? 當一個 Redis 對象的引用計數變為0時,表示沒有任何其他對象引用它,此時 Redis 會立即釋放這個對象所占用的內存空間。因此,Redis 的內存回收是實時且確定性的,不需要像Java那樣等待垃圾收集器不定時地進行掃描和清理無用對象的過程。