Redis緩存淘汰策略與Redis鍵的過時刪除策略並不徹底相同,前者是在Redis內存使用超過必定值的時候(通常這個值能夠配置)使用的淘汰策略;然後者是經過按期刪除+惰性刪除二者結合的方式進行內存淘汰的。緩存,不是存儲,沒法保證之前設置的緩存絕對存在。由於緩存容量是有上限的,即便set值的時候不設置過時時間,在內存不夠的時候,會根據內存淘汰策略刪除一些緩存。設置過時時間的key是如何刪除的?過時後會當即釋放內存嗎?redis
Redis過時Key清理的機制對清理的頻率和最大時間都有限制,在儘可能不影響正常服務的狀況下,進行過時Key的清理,以達到長時間服務的性能最優。redis會把設置了過時時間的key放在單獨的字典中,每隔一段時間執行一次刪除(在redis.conf配置文件設置hz,1s刷新的頻率)過時key的操做。算法
具體的算法以下:數據庫
這是一個基於機率的簡單算法,基本的假設是抽出的樣本可以表明整個key空間,redis持續清理過時的數據直至將要過時的key的百分比降到了25%如下。這也意味着在長期來看任何給定的時刻已通過期但仍佔據着內存空間的key的量最多爲每秒的寫操做量除以4。緩存
根據以上原理,系統中應避免大量的key同時過時,給要過時的key設置一個隨機範圍。服務器
優勢:經過限制刪除操做的時長和頻率,來減小刪除操做對CPU時間的佔用,處理"定時刪除"的缺點,按期刪除過時key,處理"惰性刪除"的缺點
缺點:在內存友好方面,不如"定時刪除" 在CPU時間友好方面,不如"惰性刪除"
難點:合理設置刪除操做的執行時長(每次刪除執行多長時間)和執行頻率(每隔多長時間作一次刪除),這個要根據服務器運行狀況來定了dom
過時的key並不必定會立刻刪除,還會佔用着內存。 當你真正查詢這個key時,redis會檢查一下,這個設置了過時時間的key是否過時了? 若是過時了就會刪除,返回空。這就是惰性刪除。ide
優勢:刪除操做只發生在從數據庫取出key的時候發生,並且只刪除當前key,因此對CPU時間的佔用是比較少的,並且此時的刪除是已經到了非作不可的地步(若是此時還不刪除的話,咱們就會獲取到了已通過期的key了)
缺點:若大量的key在超出超時時間後,好久一段時間內,都沒有被獲取過,那麼可能發生內存泄露(無用的垃圾佔用了大量的內存)性能
在設置key的過時時間的同時,爲該key建立一個定時器,讓定時器在key的過時時間來臨時,對key進行刪除。this
優勢:保證內存被儘快釋放
缺點:若過時key不少,刪除這些key會佔用不少的CPU時間,在CPU時間緊張的狀況下,CPU不能把全部的時間用來作要緊的事兒,還須要去花時間刪除這些key,定時器的建立耗時,若爲每個設置過時時間的key建立一個定時器(將會有大量的定時器產生),性能影響嚴重
結論:此方法基本上沒人用spa
過時key對RDB沒有任何影響
1)從內存數據庫持久化數據到RDB文件,持久化key以前,會檢查是否過時,過時的key不進入RDB文件
2)從RDB文件恢復數據到內存數據庫,數據載入數據庫以前,會對key先進行過時檢查,若是過時,不導入數據庫(主庫狀況)
過時key對AOF沒有任何影響
1)從內存數據庫持久化數據到AOF文件:當key過時後,尚未被刪除,此時進行執行持久化操做(該key是不會進入aof文件的,由於沒有發生修改命令)當key過時後,在發生刪除操做時,程序會向aof文件追加一條del命令(在未來的以aof文件恢復數據的時候該過時的鍵就會被刪掉)
2)AOF重寫:重寫時,會先判斷key是否過時,已過時的key不會重寫到aof文件
當redis內存超出物理內存限制時,會和磁盤產生swap,這種狀況性能極差,通常是不容許的。經過設置 maxmemory 限制最大使用內存。超出限制時,根據redis提供的幾種內存淘汰機制讓用戶本身決定如何騰出新空間以提供正常的讀寫服務。
public class LRUCache<K,V> extends LinkedHashMap<K,V> { private int cacheSize; public LRUCache(int cacheSize){ super(10,0.75f,true); //設置hashmap大小,true是讓linkedhashmap按照訪問順序排序 this.cacheSize = cacheSize; } @Override protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { //當map中數量大於指定緩存個數的時候,自動刪除最老的數據 return size()>cacheSize; } }