redis 的過期策略都有哪些?內存淘汰機制都有哪些?手寫一下 LRU 代碼實現?

面試官心理分析

如果你連這個問題都不知道,上來就懵了,回答不出來,那線上你寫代碼的時候,想當然的認為寫進redis的數據就一定會存在,后面導致系統各種 bug,誰來負責?

常見的問題:

往redis寫入的數據怎么沒了?

可能有同學會遇到,在生產環境的redis經常會丟掉一些數據,寫進去了,過一會兒可能就沒了。我的天,同學,你問這個問題就說明 redis 你就沒用對啊。redis 是緩存,你給當存儲了是吧?

啥叫緩存?用內存當緩存。內存是無限的嗎,內存是很寶貴而且是有限的,磁盤是廉價而且是大量的。可能一臺機器就幾十個G的內存,但是可以有幾個 T 的硬盤空間。redis 主要是基于內存來進行高性能、高并發的讀寫操作的。

那既然內存是有限的,比如redis就只能用 10G,你要是往里面寫了 20G 的數據,會咋辦?當然會干掉10G 的數據,然后就保留 10G 的數據了。那干掉哪些數據?保留哪些數據?當然是干掉不常用的數據,保留常用的數據了。數據明明過期了,怎么還占用著內存?這是由redis的過期策略來決定。

面試題剖析

redis 過期策略?

redis過期策略是:定期刪除+惰性刪除。

所謂定期刪除,指的是redis默認是每隔 100ms 就隨機抽取一些設置了過期時間的 key,檢查其是否過期,如果過期就刪除。

假設redis里放了 10w 個 key,都設置了過期時間,你每隔幾百毫秒,就檢查 10w 個 key,那 redis 基本上就死了,cpu 負載會很高的,消耗在你的檢查過期 key 上了。注意,這里可不是每隔 100ms 就遍歷所有的設置過期時間的 key,那樣就是一場性能上的災難。實際上 redis 是每隔 100ms 隨機抽取一些key 來檢查和刪除的。

但是問題是,定期刪除可能會導致很多過期key到了時間并沒有被刪除掉,那咋整呢?所以就是惰性刪除了。這就是說,在你獲取某個 key 的時候,redis 會檢查一下 ,這個 key 如果設置了過期時間那么是否過期了?如果過期了此時就會刪除,不會給你返回任何東西。

獲取key的時候,如果此時 key 已經過期,就刪除,不會返回任何東西。

但是實際上這還是有問題的,如果定期刪除漏掉了很多過期key,然后你也沒及時去查,也就沒走惰性刪除,此時會怎么樣?如果大量過期 key 堆積在內存里,導致 redis 內存耗盡了,咋整?

答案是:走內存淘汰機制。

內存淘汰機制

redis內存淘汰機制有以下幾個:

· noeviction:當內存不足以容納新寫入數據時,新寫入操作會報錯,這個一般沒人用吧,實在是太惡心了。

· allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的 key(這個是最常用的)。

· allkeys-random:當內存不足以容納新寫入數據時,在鍵空間中,隨機移除某個 key,這個一般沒人用吧,為啥要隨機,肯定是把最近最少使用的key給干掉啊。

· volatile-lru:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,移除最近最少使用的key(這個一般不太合適)。

· volatile-random:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,隨機移除某個key。

· volatile-ttl:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,有更早過期時間的key優先移除。

?手寫一個LRU 算法

你可以現場手寫最原始的LRU算法,那個代碼量太大了,似乎不太現實。

不求自己純手工從底層開始打造出自己的LRU,但是起碼要知道如何利用已有的 JDK 數據結構實現一個Java版的 LRU。

class LRUCache<K, V> extends LinkedHashMap<K, V> {

private final int CACHE_SIZE;

/** * 傳遞進來最多能緩存多少數據 * * @param cacheSize 緩存大小 */

public LRUCache(int cacheSize) {

// true 表示讓 linkedHashMap 按照訪問順序來進行排序,最近訪問的放在頭部,最老訪問的放

在尾部。

super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true);

CACHE_SIZE = cacheSize;

}

@Override

protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {

// 當 map 中的數據量大于指定的緩存個數的時候,就自動刪除最老的數據。

return size() > CACHE_SIZE;

}

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容