# 記憶體清理策略
# volatile-lru -> 對所有設定了過期時間的key使用lru演算法進行刪除
# allkeys-lru -> 對所有key使用lru演算法進行刪除
# volatile-lfu -> 對所有設定了過期時間的key使用lfu演算法進行刪除
# allkeys-lfu -> 對所有key使用lfu演算法進行刪除
# volatile-random -> 對所有設定了過期時間的key使用隨機演算法進行刪除
# allkeys-random -> 對所有key使用隨機演算法進行刪除
# volatile-ttl -> 刪除馬上要過期的key
# noeviction -> 永不過期,不會刪除任何key
預設:6.0.8版本淘汰策略是:noeviction,只要沒有被動過期,就不會主動過期,這是預設的淘汰策略。
1.一般不建議使用隨機:random,因為不怎麼科學刪除;如果存在熱點key被清除了,那麼快取擊穿、穿透,就會有問題;
2.那麼什麼是lru演算法、lfu演算法呢?
講故事說明:
如果說乙個老奶奶,有三個兒子;然後大兒子,在最近一年內都沒有回來過,那麼就可以認為這個兒子不合格,那麼就可以認為這個大兒子,在接下來的日子也是不會回來的,就斷絕母子關係了,這就是lru演算法,在最近的一段時間內一直都沒有被訪問到這個key;那麼就會認為這個key在之後也不會被訪問到了,那麼就會被淘汰;
那麼二兒子,在最近一年內就回來過一次,那麼就可以認為這個二兒子,在接下來的日子也是不會回來的,就斷絕母子關係了,這就是lfu演算法,在最近的一段時間內很少訪問到這個key;那麼就會認為這個key在之後也不會被訪問到了,那麼就會被淘汰;
(舉例不是很形象,但是是那麼個意思)
那麼舉其他例子呢?就好比,我們的手機的程序記憶體,要知道,我們的手機記憶體是優先的,會經常碰到乙個問題就是,殺程序。假設我們的手機記憶體是8g,那也會有上限;
那麼這個使用就會有過期淘汰程序了。
關於這個lru演算法,那麼我們就需要設計乙個演算法來討論一下:
鍊錶 + hash;
鍊錶是控制優先順序順序,hash控制是快速定位到具體的內容
1.巧妙使用linkedhashmap實現(jdk支援api)
public class lrudemo extends linkedhashmap
@override
protected boolean removeeldestentry(map.entry eldest)
}
那麼測試
public static void main(string args)
結果如下:
看看實現原始碼
翻譯一下:
乙個特殊的是提供以建立鏈結的哈希圖,其迭代順序為順序上次訪問其條目的時間,從最近到最近(訪問順序)。這種地圖非常適合建立lru快取。
官方文件都說明了lru的實現原理,那麼想知道lru演算法如何實現,那麼就看看linkedhashmap結構把。
2.手動構造 雙向鍊錶 + hash雜湊 o(1)
其中map用於定位,linked為雙向鍊錶,維護出隊,入頭位;
public class lrudemo2
public node(k key, v value)
}static class doublelinkedlist
/*** 新增節點
** @param node
*/public void addnode(nodenode)
/*** 刪除節點
** @param node
*/public void removenode(nodenode)
/*** 獲取最後乙個節點
** @return
*/public nodegetlastnode()
}public lrudemo2(int cachesize)
/*** 獲取節點
** @param key
* @return
*/public int getkey(int key)
nodenode = map.get(key);
//將該節點活躍前置
this.linked.removenode(node);
this.linked.addnode(node);
return node.value;
}/**
* 新增節點
** @param key
* @param value
*/public void put(int key, int value) else
node = new node<>(key, value);
this.map.put(key, node);
}this.linked.addnode(node);}}
執行演算法
public class lrudemo2
}
結果
總結:lru演算法,是一種 活躍淘汰演算法,按照鍊錶實現,可以使用hash快速查詢、通過雙向鍊錶繫結,進行活躍前置,不活躍則解除可達性引用,被gc;那麼我們上述沒有實現get,最近使用前置,但是演算法中已經實現了。原理是一樣的,當該key被使用,那麼我們將該node先解綁、再重新繫結前置;lru演算法,就是一種最近未使用淘汰演算法;
lfu演算法就是一種最近不怎麼使用的淘汰演算法;
兩者區別為:lru針對時間角度進行淘汰(最新資料);lfu為針對使用頻率進行淘汰(熱點資料);
各有千秋,針對業務的不同,那麼我們將使用不同的淘汰演算法(筆者使用的是 「對設定過過期時間的key進行 熱點資料 淘汰演算法」)
Redis最大記憶體淘汰策略
redis記憶體超出物理記憶體的限制的時候,會產生記憶體對換 swap 現象,與高速的redis思想相違背。因此生產環境中,不允許redis有記憶體交換行為,redis提供了配置引數maxmemory限制記憶體。實際記憶體超出maxmemory的時候,redis提供了幾種可選淘汰策略。不會繼續服務寫...
Redis之最大記憶體置換策略
redis預設最大記憶體大小是應用程式可訪問的記憶體大小,32位windows下是2gb,linux下是3gb.64位下可以訪問的記憶體為2 64位元組,redis提供了maxmemory欄位來限制使用的最大記憶體.既然提供了最大記憶體限制,那麼當我們程式達到最大值時,redis使用了多種策略進行置...
redis設定最大記憶體,及淘汰策略
redis設定最大記憶體,及淘汰策略 命令info查詢redis的記憶體及淘汰策略 used memory 由 redis 分配器分配的記憶體總量,包含了redis程序內部的開銷和資料占用的記憶體,以位元組 byte 為單位 used memory human 以更直觀的可讀格式顯示返回使用的記憶體...