least recently used,即最近最少使用,是記憶體管理的一種頁面置換演算法。演算法的核心是:如果乙個資料在最近一段時間內沒有被訪問到,那麼它在將來被訪問的可能性也很小。換言之,當記憶體達到極限時,應該把記憶體中最久沒有被訪問的資料淘汰掉。
理論上只需要乙個列表,資料被使用時,不在lru列表中就放到頭部,在就提到頭部,相應淘汰尾部的資料即可。或者資料使用時記錄使用時間戳,每次比對時間戳,最小的淘汰。
使用hashmap可以使時間複雜度由o(n)降低至o(1)。
使用python 雙向鍊錶+hashmap
from collections import ordereddict
class lrudict(ordereddict):
def __init__(self, capacity):
self.capacity = capacity
self.items = ordereddict()
def __setitem__(self, key, value):
old_value = self.items.get(key)
if old_value is not none:
self.items.pop(key)
self.items[key] = value
elif len(self.items) < self.capacity:
self.items[key] = value
else:
self.items.popitem(last=false)
self.items[key] = value
def __getitem__(self, key):
value = self.items.get(key)
if value is not none:
self.items.pop(key)
self.items[key] = value
return value
def __repr__(self):
return repr(self.items)
一種策略不是萬能的,不同的場景決定了不同的用法
redis占用記憶體達到極限時,就需要將一部分資料寫入磁碟,此時就需要一種策略來決定的是哪一部分寫入磁碟。
redis放在記憶體中,雙向鍊錶+hashmap 這樣占用比較大的結構比較奢侈。redis需要採用更節省空間的實現方式。
redis 在實現上引入了乙個 lru 時鐘來代替 unix 時間戳,每個物件的每次被訪問都會記錄下當前伺服器的 lru 時鐘,然後用伺服器的 lru 時鐘減去物件本身的時鐘,得到的就是這個物件沒有被訪問的時間間隔(也稱空閒時間),空閒時間最大的就是需要淘汰的物件。redis則隨機選取 若干(server.maxmemory_samples配置) 個 key,然後比較它們的lru訪問時間,然後淘汰最近最久沒有訪問的key。(假設maxmemory_samples為最大即當前key數量,每次比較所有key的lru訪問時間,此時演算法由回到了樸素的lru演算法)
sql經常會有全表掃瞄這樣的查詢,如果使用樸素lru演算法,緩衝池的頁會被經常刷完,起不到緩衝的作用。
加入midpoint,資料進來先加入到midpoint,在根據設定的時間提到lru列表頭。
lfu(least frequently used ,最近最少使用演算法)也是一種常見的快取演算法。
顧名思義,lfu演算法的思想是:如果乙個資料在最近一段時間很少被訪問到,那麼可以認為在將來它被訪問的可能性也很小。因此,當空間滿時,最小頻率訪問的資料最先被淘汰。
演算法實現策略:考慮到 lfu 會淘汰訪問頻率最小的資料,我們需要一種合適的方法按大小順序維護資料訪問的頻率。lfu 演算法本質上可以看做是乙個 top k 問題(k = 1),即選出頻率最小的元素,因此我們很容易想到可以用二項堆來選擇頻率最小的元素,這樣的實現比較高效。最終實現策略為小頂堆+雜湊表。
redis4.0提供lfu演算法。lfu演算法如果有資料短時高頻訪問,則會一直留在記憶體中
快取淘汰演算法 LRU
1.lru 1.1.原理 lru least recently used,最近最少使用 演算法根據資料的歷史訪問記錄來進行淘汰資料,其核心思想是 如果資料最近被訪問過,那麼將來被訪問的機率也更高 1.2.實現 最常見的實現是使用乙個鍊錶儲存快取資料,詳細演算法實現如下 1.新資料插入到鍊錶頭部 2....
LRU 快取淘汰演算法
1.介紹 lru是leastrecentlyused近期最少使用演算法。記憶體管理的一種頁面置換演算法,對於在記憶體中但又不用的資料塊 記憶體塊 叫做lru,oracle會根據哪些資料屬於lru而將其移出記憶體而騰出空間來載入另外的資料。lru least recently used,最近最少使用 ...
LRU快取淘汰演算法
這是乙個什麼演算法?這是乙個可以處理程式過多的情況下該刪除哪乙個程式的演算法策略。它是根據最近使用時間來進行確定的,通常刪除的是最後乙個節點。那麼這個演算法會涉及什麼樣的資料結構?這個演算法涉及了hashmap和雙向鍊錶的資料結構,通過這兩個結構的配合可以通過map來快速定位訪問節點,通過雙向鍊錶來...