關於redis 超過最大記憶體限制,觸發淘汰策略說明

2021-10-11 23:29:49 字數 3008 閱讀 5930

# 記憶體清理策略

# 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 以更直觀的可讀格式顯示返回使用的記憶體...