一、redis的過期策略和內存淘汰機制
1、定期刪除+惰性刪除
定期刪除:指的是redis默認是每隔100ms就隨機抽取一些設置了過期時間的key,檢查其是否過期,如果過期就刪除
惰性刪除:在你獲取某個key的時候,redis會檢查一下 ,這個key如果設置了過期時間那么是否過期了,如果過期了此時就會刪除,不會給你返回任何東西
2、如果大量過期key堆積在內存里,導致redis內存塊耗盡了,怎么辦?
內存淘汰機制:
redis.conf中配置:
# maxmemory-policy noeviction
noeviction:當內存使用達到閾值的時候,所有引起申請內存的命令會報錯。
allkeys-lru:在主鍵空間中,優先移除最近未使用的key。
volatile-lru:在設置了過期時間的鍵空間中,優先移除最近未使用的key。
allkeys-random:在主鍵空間中,隨機移除某個key。
volatile-random:在設置了過期時間的鍵空間中,隨機移除某個key。
volatile-ttl:在設置了過期時間的鍵空間中,具有更早過期時間的key優先移除。
二、手寫LRU緩存
public class LRUCache {
private Map<Integer, Integer> map;
private final int capacity;
public LRUCache(int capacity) {
this.capacity = capacity;
//定義了迭代順序,該迭代順序可以是插入順序或者是訪問順序(true)
map = new LinkedHashMap<Integer, Integer>(capacity,0.75f,true){
@Override
protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
//當map中的數據量大於指定的緩存個數的時候,就自動刪除最老的數據
return size() > capacity;
}
};
}
public int get(int key) {
return map.getOrDefault(key, -1);
}
public void put(int key, int value) {
map.put(key, value);
}
}
LinkedHashMap的源碼說明 :
對於 LinkedHashMap 而言,它繼承與 HashMap(public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>)、
底層使用哈希表與雙向鏈表來保存所有元素。
LinkedHashMap 中的 Entry 集成與 HashMap 的 Entry,但是其增加了 before 和 after 的引用,指的是上一個元素和下一個元素的引用
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}
初始化:
在 LinkedHashMap 的構造方法中,實際調用了父類 HashMap 的相關構造方法來構造一個底層存放的 table 數組,但額外可以增加 accessOrder 這個參數,如果不設置,默認為 false,代表按照插入順序進行迭代;當然可以顯式設置為 true,代表以訪問順序進行迭代
public LinkedHashMap(int initialCapacity,
float loadFactor,
boolean accessOrder) {
super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;
}
