Redis緩存穿透,緩存擊穿和緩存雪崩

一、緩存處理流程

處理Reids緩存引發的問題時,我們首先得知道緩存處理的一個流程,如下圖:
在這裏插入圖片描述

二、緩存穿透,緩存擊穿和緩存雪崩

緩存穿透
描述:緩存穿透是指緩存和數據庫中都沒有的數據,而用戶不斷髮起請求,如發起爲id爲“-1024”的數據或id爲特別大不存在的數據。這時的用戶很可能是攻擊者,攻擊會導致數據庫壓力過大。
解決方法:
1.接口層增加校驗,如用戶鑑權校驗,id做基礎校驗,id<=0的直接攔截;
2.從緩存取不到的數據,在數據庫中也沒有取到,這時也可以將key-value對寫爲key-null,緩存有效時間可以設置短點,如30秒(設置太長會導致正常情況也沒法使用)。這樣可以防止攻擊用戶反覆用同一個id暴力攻擊
3.採用布隆過濾器,將所有可能存在的數據哈希到一個足夠大的bitmap中,一個一定不存在的數據會被 這個bitmap攔截掉,從而避免了對底層存儲系統的查詢壓力。

緩存擊穿
描述:緩存擊穿是指緩存中沒有但數據庫中有的數據(一般是緩存時間到期),這時由於併發用戶特別多,同時讀緩存沒讀到數據,又同時去數據庫去取數據,引起數據庫壓力瞬間增大,造成過大壓力
解決方法
1.設置熱點數據永遠不過期
2.加互斥鎖,互斥鎖參考代碼如下:

public String get(key) {
      String value = redis.get(key);
      if (value == null) { //代表緩存值過期
          //設置3min的超時,防止del操作失敗的時候,下次緩存過期一直不能load db
            if (redis.setnx(key_mutex, 1, 3 * 60) == 1) {  //代表設置成功
                     value = db.get(key);
                      redis.set(key, value, expire_secs);
                      redis.del(key_mutex);
              } else {  //這個時候代表同時候的其他線程已經load db並回設到緩存了,這時候重試獲取緩存值即可
                      sleep(50);
                      get(key);  //重試
              }
          } else {
              return value;      
          }
 }

緩存雪崩
描述:緩存雪崩是指緩存中數據大批量到過期時間,而查詢數據量巨大,引起數據庫壓力過大甚至down機。和緩存擊穿不同的是,緩存擊穿指併發查同一條數據,緩存雪崩是不同數據都過期了,很多數據都查不到從而查數據庫。
解決方法
1.緩存數據的過期時間設置隨機,防止同一時間大量數據過期現象發生。
2.如果緩存數據庫是分佈式部署,將熱點數據均勻分佈在不同搞得緩存數據庫中。
3.設置熱點數據永遠不過期。

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