爲了更好的利用內存,使Redis存儲的都是緩存的熱點數據,Redis設計了相應的內存淘汰機制(也叫作緩存淘汰機制)java
經過maxmemory 配置項來設置容許用戶使用的最大內存大小,當內存數據集大小達到必定的大小時,就會根據maxmemory-policy noeviction配置項配置的策略來進行數據淘汰。git
默認爲no-eviction策略github
從已設置過時時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰redis
從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰算法
從已設置過時時間的數據集(server.db[i].expires)中挑選將要過時的數據淘汰spring
從已設置過時時間的數據集(server.db[i].expires)中任意選擇數據淘汰緩存
從數據集(server.db[i].dict)中任意選擇數據淘汰數據結構
禁止驅逐數據,永遠不過時,僅對寫操做返回一個錯誤,默認爲該項dom
Redis 肯定驅逐某個鍵值對後,會刪除這個數據,並將這個數據變動消息發佈到本地(AOF 持久化)和從機(主從鏈接)spring-boot
實際上Redis實現的LRU並非可靠的LRU,也就是名義上咱們使用LRU算法淘汰鍵,可是實際上被淘汰的鍵並不必定是真正的最久沒用的,這裏涉及到一個權衡的問題,若是須要在所有鍵空間內搜索最優解,則必然會增長系統的開銷,Redis是單線程的,也就是同一個實例在每個時刻只能服務於一個客戶端,因此耗時的操做必定要謹慎。爲了在必定成本內實現相對的LRU,早期的Redis版本是基於採樣的LRU,也就是放棄所有鍵空間內搜索解改成採樣空間搜索最優解。自從Redis3.0版本以後,Redis做者對於基於採樣的LRU進行了一些優化,目的是在必定的成本內讓結果更靠近真實的LRU。
Redis 數據集數據結構中保存了鍵值對過時時間的表,即 redisDb.expires,在使用 SET 命令的時候,就有一個鍵值對超時時間的選項。 從過時時間 redisDB.expires 表中隨機挑選幾個鍵值對,取出其中 ttl 最大的鍵值對淘汰。一樣TTL淘汰策略並非全部過時時間的表中最快過時的鍵值對,而只是隨機挑選的幾個鍵值對。
在隨機淘汰的場景下獲取待刪除的鍵值對,隨機找hash桶再次hash指定位置的dictEntry便可
Redis中的淘汰機制(LRU和TTL)都是非精確算法實現的,主要從性能和可靠性上作平衡,因此並非徹底可靠,在瞭解Redis淘汰策略以後還應在平時多主動設置或更新key的expire時間,主動刪除沒有價值的數據,提高Redis總體性能和空間