1. 程式人生 > >redis 的過期策略都有哪些?記憶體淘汰機制都有哪些?手寫一下 LRU 程式碼實現?

redis 的過期策略都有哪些?記憶體淘汰機制都有哪些?手寫一下 LRU 程式碼實現?

面試題

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;
    }
}

本文在米兜公眾號連結:
https://mp.weixin.qq.com/s/h3XyW1WgPY9fcMmSMb6pHw

歡迎關注米兜Java,一個注在共享、交流的Java學習平臺。

相關推薦

redis過期策略哪些記憶體淘汰機制哪些一下 LRU 程式碼實現

面試題 redis 的過期策略都有哪些?記憶體淘汰機制都有哪些?手寫一下 LRU 程式碼實現? 面試官心理分析 如果你連這個問題都不知道,上來就懵了,回答不出來,那線上你寫程式碼的時候,想當然的認為寫進 redis 的資料就一定會存在,後面導致系統各種 bug,誰來負責? 常見的有兩個問題: 往 red

Redis過期策略記憶體淘汰策略、持久化策略

一、持久化策略 1.基本概念  Redis的資料是存在記憶體中的,若redis宕機,資料就會全部丟失 (1)RDB快照,是一次全量備份,快照是記憶體資料的二進位制序列化形式,儲存上非常緊湊; (2)AOF日誌,是連續的增量備份,AOF日誌記錄的是記憶體資料修改的指令記錄

Redis過期策略以及記憶體淘汰機制

過期鍵刪除策略 我們都知道,刪除鍵的目的,就是釋放記憶體佔用。那麼,當一個鍵過期了,Redis 什麼時候會去刪除她呢? 定時刪除 設定鍵的過期時間時,建立一個 Timer ,當過期時間到臨時,立刻刪除鍵。 記憶體友好型策略,一旦鍵過期,就會被刪除,並釋放所佔用的記憶體,Cpu 不友好,當一批數量

Redis(六)--- Redis過期策略記憶體淘汰機制、訊息及事物

1、簡述 (1)關於Redis鍵的過期策略,首先要了解兩種時間的區別,生存時間和過期時間; 生存時間:一段時長,如30秒、6000毫秒,設定鍵的生存時間就是設定這個鍵可以存在多長時間,命令有兩個 expire(秒)、pexpire(毫秒)(可以參考 Redis(四)--- R

redis過期策略記憶體淘汰機制分析

過期策略:   我們在set key時,可以給一個expire time,就是過期時間   這段過期時間以後,redis對key刪除使用:定期刪除+惰性刪除   定期刪除指redis預設在100ms內隨機抽取一些設定了過期時間的key,檢查是否過期,過期就刪除。   定期刪除因為隨機的,很多key沒有

Redis 原理及應用(3)--記憶體淘汰機制、主從同步原理,HA策略(哨兵機制)分析

非精準的LRU 上面提到的LRU(Least Recently Used)策略,實際上Redis實現的LRU並不是可靠的LRU,也就是名義上我們使用LRU演算法淘汰鍵,但是實際上被淘汰的鍵並不一定是真正的最久沒用的,這裡涉及到一個權衡的問題,如果需要在全部鍵空間內搜尋最優解,則必然會增加系統的開銷,Re

Redis過期策略

link 進行 變量 耗時 ron del 配置 alt als Redis過期策略 原文轉載:https://www.cnblogs.com/java-zhao/p/5205771.html 1、設置過期時間 expire key time(以秒為單位)--這是最常用的

redis - 過期策略

Redis 所有的資料結構都可以設定過期時間,時間一到,就會自動刪除。你可以想象 Redis 內部有一個死神,時刻盯著所有設定了過期時間的 key,壽命一到就會立即收割。        你還可以進一步站在死神的角度思考,會不會因為同一時間太多的 ke

redis過期策略實現機制

參考:https://www.cnblogs.com/xuliangxing/p/7151812.html 一、redis設定過期時間     將某個key設定過期時間:expire key time(以秒為單位)     原子方式,同時設定值和過

Redis 記憶體淘汰機制

簡介 Redis記憶體淘汰指的是使用者儲存的一些鍵被可以被Redis主動地從例項中刪除,從而產生讀miss的情況,那麼Redis為什麼要有這種功能?這就是我們需要探究的設計初衷。Redis最常見的兩種應用場景為快取和持久儲存,首先要明確的一個問題是記憶體淘汰策略更適

Redis 過期策略

redis設定過期時間 expire key time(以秒為單位)–這是最常用的方式 setex(String key, int seconds, String value)–字串獨有

作業系統頁面置換演算法與redis記憶體淘汰機制

寫在前面:最近碰到作業系統中關於頁面置換的一些問題,與此同時學習redis的過程中發現它的記憶體淘汰機制有些相似,在此一併記錄下來。 首先是作業系統中的頁面替換演算法 最佳置換演算法(OPT) 這是一種理想情況下的頁面置換演算法,但實際上是不可能實現的。該

Redis過期策略 實現原理

我們在使用redis時,一般會設定一個過期時間,當然也有不設定過期時間的,也就是永久不過期。 當我們設定了過期時間,redis是如何判斷是否過期,以及根據什麼策略來進行刪除的。 1.redis設定過期時間:expire 只針對頂級key有效,即雜湊結構不支援過期  

Redis過期策略實現原理

一段時間 ase 常用 減少 不存在 假設 exp 三種 壓力 我們在使用redis時,一般會設置一個過期時間,當然也有不設置過期時間的,也就是永久不過期。 當我們設置了過期時間,redis是如何判斷是否過期,以及根據什麽策略來進行刪除的。 redis設置過期時間:expi

redis evict.c記憶體淘汰機制的原始碼分析

           眾所周知,redis是一個記憶體資料庫,所有的鍵值對都是儲存在記憶體中。當資料變多之後,由於記憶體有 限就要淘汰一些鍵值對,使得記憶體有足夠的空間來儲存新的鍵值對。在redis中,通過設定server.maxmemory 來限定記憶體的使用(serve

搞定redis面試--Redis過期策略一個LRU

過期策略 問題 protect 惰性 存儲 什麽 不出 結果 true 1 面試題 Redis的過期策略都有哪些?內存淘汰機制都有哪些?手寫一下LRU代碼實現? 2 考點分析 1)我往redis裏寫的數據怎麽沒了? 我們生產環境的redi

老司機帶你玩轉面試(2):Redis 過期策略以及快取雪崩、擊穿、穿透

![](https://cdn.geekdigging.com/Interview/mianshi_header_1.jpg) ## 前文回顧 建議前一篇文章沒看過的同學先看下前面的文章: [「老司機帶你玩轉面試(1):快取中介軟體 Redis 基礎知識以及資料持久化」](https://www.gee

Redis記憶體淘汰機制

概述 Redis是基於記憶體儲存,常用於資料的快取,所以Redis提供了對鍵的過期時間的設定,實現了幾種淘汰機制便於適應各種場景。 設定過期時間 我們可以在設定鍵時設定expire time,也可以在執行時給存在的鍵設定剩餘的生存時間,不設定則預設為-1,設定為-1時表示永久儲存。 Redis清除過

Redis 記憶體淘汰機制詳解

一般來說,快取的容量是小於資料總量的,所以,當快取資料越來越多,Redis 不可避免的會被寫滿,這時候就涉及到 Redis 的記憶體淘汰機制了。我們需要選定某種策略將“不重要”的資料從 Redis 中清除,為新的資料騰出空間。 # 配置 Redis 記憶體大小 我們應該為 Redis 設定多大的記憶體容量

用SVM(核和無核函式)進行MNIST字型的分類

1.普通SVM分類MNIST資料集 1 #匯入必備的包 2 import numpy as np 3 import struct 4 import matplotlib.pyplot as plt 5 import os 6 ##載入svm模型 7 from sklearn import