談談redis緩存擊穿透和緩存擊穿的區別,雪崩效應


面試經歷

在很長的一段時間里,我以為緩存擊穿和緩存穿透是一個東西,直到最近去騰訊面試,面試官問我緩存擊穿和穿透的區別;我回答它倆是一樣的,面試官馬上抬起頭用他那細長的單眼皮眼睛瞪着我說:“你確定嗎?”,最后面試提醒我,既然有不同的名字,那他們肯定就是不一樣的,也就是說緩存擊穿和緩存穿透不是一個東西;

那么今天我們就看看這倆玩意的區別,以及它們引發的后果;

在項目中加入緩存

一般情況下,我們會把熱點數據放到緩存中,比如常用的字典、用戶信息、訂單詳情等等;也就是說,當項目啟動后,先將熱點數據加載到redis中,以后需要數據時就不用每次都去數據庫查詢了,這樣一來,既減少了數據庫的壓力,也提升了訪問速度,可謂是一舉多得呀!
在這里插入圖片描述

緩存穿透

緩存穿透是指緩存和數據庫中都沒有的數據,而用戶不斷發起請求,如發起為id為“-1”的數據或id為特別大不存在的數據。這時的用戶很可能是攻擊者,攻擊會導致數據庫壓力過大。
在這里插入圖片描述

解決方案:

  1. 接口層增加校驗,如用戶鑒權校驗,id做基礎校驗,id<=0的直接攔截;
  2. 從緩存取不到的數據,在數據庫中也沒有取到,這時也可以將key-value對寫為key-null,緩存有效時間可以設置短一些,如30秒(設置太長會導致正常情況也沒法使用)。這樣可以防止攻擊用戶反復用同一個id暴力攻擊

緩存擊穿

緩存擊穿指的是大量的key在同一時間過期,但是又有大量的請求需要用到這些已經過期的key,那么程序在redis找不到數據,就會去數據庫里查詢,數據庫處理大量的請求的同時導致壓力瞬間增大,造成壓力過大,甚至導致崩潰;
在這里插入圖片描述
解決方案

  1. 設置key值永不過期
  2. 將key的過期時間設為隨機
  3. 增加互斥鎖,當多個key過期時,同一時間只有一個查詢請求下發到數據庫,其他的key等待一個個地輪流查,就可以避免數據庫壓力過大的問題;代碼如下:
    static Lock lock = new ReentrantLock();
    
    public String getData(String key ) throws InterruptedException {
        try {
            // 從redis獲取值
            String data =  getRedisData(key);
            // 如果key不存在,從數據庫查詢
            if(null  == data){
                // 嘗試獲取鎖
                if(!lock.tryLock()){
                   // 獲取鎖失敗 ,100ms后在次嘗試
                    TimeUnit.MILLISECONDS.sleep(100);
                    data = getData(key);
                }
                // 走到這里表示成功獲取鎖

                // 從myqsl中獲取鎖
                data = getMysqlData(key);

                // 將數據更新到redis
                setDataToRedis(key,value);
            }
            return data;
        } catch (Exception e){
            e.printStackTrace();
            throw e;
        } finally {
            // 解鎖
            lock.unlock();
        }
    }

穿透和擊穿的區別

關於穿透和擊穿的區別上面已經介紹的很清楚了,這里在做個總結

  • 穿透 :大量請求了緩存和數據庫中都沒有的數據,每次都查詢數據庫,導致數據庫壓力過大
  • 擊穿 : 大量key在同一時間過期,導致所有請求都達到數據庫,導致數據庫壓力過大

雪崩效應

雪崩效應指的是由穿透和擊穿引起的數據庫壓力過大,最后導致整個數據庫宕機,一旦數據庫崩了,它所帶來的連鎖反應是可怕的,數據庫不可用的情況下你的服務器也無法使用;這就是雪崩效應;
在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM