緩存穿透和緩存雪崩

緩存穿透和緩存雪崩


緩存穿透

  • 概念

    所謂緩存穿透就是說在緩存中不存在,然後直接在數據庫中查詢的現象,圖例如下:

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ih0ayfgO-1578143845324)(D:\學習總結\redis\緩存穿透.png)]

  • 場景

    一般來說,緩存穿透的場景發生在故意攻擊的場景下;比如說,本來查詢意見商品的序號是正數,但是請求方總是請求大量的負數過來,導致緩存無效,全部流量都打在了數據庫中,如果某一時刻流量過大,則會導致數據庫崩潰;

  • 解決方案

    • 方案一:布隆過濾器
      • 布隆過濾器會判斷某個元素是否在某個幾個中,相關的知識點會專門去介紹。
    • 方案二:緩存空值
      • 可以把一些不符合要求的數據的key值設置爲NULL,這樣就不會一直去查數據庫了但是需要設置過期時間;

    最好就是在redis前面加一個布隆過濾器,這樣很降低緩存穿透的概率;

  • 僞代碼

    ////方案一
    //僞碼
    string penetrate1(int ID,string str)
    {
        
        //使用布隆過濾器,後續專門寫一篇博客
        if(存在)
        {
            redis操作
        }
        else
        {
            return NULL;
        }
        
    }
    ////方案二
    //僞碼
    string penetrate1(int ID,string str)
    {
        //假設可以就是ID
        int CacheTime = 30;
        string CacheValue;
        char cmd[128];
        char sql[128];
        memset(cmd,0,sizeof(cmd));
        memset(sql,0,sizeof(sql));
        sprintf(cmd,"get %d",ID);
        redisReply* replay = (redisReply*)redisCommand(conn,cmd);
        if(replay->type == REDIS_REPLY_ERROR)
        {
            //查詢數據庫
            mysql_query(&mysql,sql);
            MYSQL_RES *result= mysql_store_result(&mysql);
            int row = mysql_num_rows(result);
            //查詢爲空
            if(row < 0)
            {
                //設置默認值
                memset(cmd,0,sizeof(cmd));
                sprintf(cmd,"set %d ''",ID);
                redisReply* replay = (redisReply*)redisCommand(conn,cmd);
            }
            //數據庫數據同步到redis中
            //set XX XX
            redisReply* replay = (redisReply*)redisCommand(conn,cmd);
            //返回數據
            return 結果;
        }
        else
        {
            return replay->str;
        }
        
        
    
    }   
    

緩存雪崩

  • 概念
    所謂緩存雪崩就是在某一個時刻,緩存集大量失效。所有流量直接打到數據庫上,對數據庫造成巨大壓力;

在這裏插入圖片描述

  • 場景

    基本我們能想到的場景就是一些電商搶購的現象,一般就是比如12點開始,在1點的時候大量同時失效,這個時候就會造成緩存雪崩的現象;

  • 解決方案

    • 方案一:加鎖/隊列

      • 加鎖/隊列;這樣雖然能降低數據庫壓力,但是同時,響應也很慢
    • 方案二:緩存標記

      • 給每一個緩存數據增加相應的緩存標記,記錄緩存的是否失效,如果緩存標記失效,則更新數據緩存
    • 方案三:緩存過期時間錯開

      • 設置緩存時間錯開,可以在設置過期時間的時候,加一個一定範圍內的隨機值來錯開

想了解學習更多C++後臺服務器方面的知識,請關注:
微信公衆號:C++後臺服務器開發


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章