Redis快取穿透與雪崩

發光線發表於2020-11-25

概述

在這裡插入圖片描述

快取穿透(資料庫查不到)

使用者想要查詢一個資料,發現redis中沒有,也就是快取每命中,於是向持久層資料庫中查詢,發現資料庫中也沒有,於是本次查詢失敗。當使用者很多時候,快取一直沒有命中(比如秒殺場景),於是都去請求資料庫了。這會給資料庫造成很大的壓力,這種場景就是快取穿透(簡單的說就是快取和資料庫中都沒有某條資料,就會造成快取穿透的情況)。

解決方案

  1. 布隆過濾器
    布隆過濾器是一種資料結構,對所有可能查詢的引數以hash形式儲存,在控制層先進行校驗,不符合則丟棄,從而避免了對底層儲存系統的查詢壓力。
    在這裡插入圖片描述
  2. 快取空物件
    當儲存層沒有命中後,即使返回的空物件也將其快取起來,同時會設定一個過期時間,之後在訪問這個資料將會從快取中獲取,包含了後端資料庫。
    在這裡插入圖片描述
    但是這種方法會存在兩個問題:
  3. 如果空值能夠被快取起來,這就意味著快取需要更多的空間儲存更多的鍵,因為這當中可能會有很多的空值的鍵。
  4. 即使對空值設定了過期時間,還是會在快取層和儲存層的資料會有一段時間視窗的不一致,這對於需要一致性的業務會有影響(可以通過在程式碼中新增刪除相應key的快取來解決不一致的問題,比如增加,修改了相應的key直接刪除該key對應的快取即可)。

快取擊穿(量太大,快取過期)

比如微博伺服器在有熱點事件時可能當機。(同一時刻大量的訪問在快取中沒有命中,砸向了資料庫)

概述
這裡需要注意和快取穿透的區別,快取擊穿是指一個Key非常熱點,在不停的扛著大併發,大併發集中對著一個點進行訪問,當這個key在失效的瞬間,持續的大併發就穿破快取,直接請求資料庫,就像在一個屏障上鑿開一個洞。
當某個key在過期的瞬間,有大量的請求併發訪問,這類書籍一般是熱點資料,由於快取過期,會同時訪問資料庫來查詢最新資料,並且會寫快取,會導致使資料庫瞬間壓力過大。
解決方案
設定熱點資料永不過期
從快取層面來看,沒有設定過期時間,所以不會出現熱點key過期後產生的問題。
加分散式互斥鎖
分散式鎖:使用分散式鎖,保證對於每個Key同時只有一個執行緒去查詢後端服務,其他執行緒沒有獲得分散式鎖的許可權,等待分散式鎖釋放。這種方式將高併發的壓力轉移到了分散式鎖,因此對分散式鎖的考驗很大。
在這裡插入圖片描述

快取雪崩

概念
快取雪崩,是指在某個時間段,快取集中過期失效或者redis當機。
產生雪崩的原因之一,比如在雙十一的時候,大量的使用者會去搶購一波商品,這波商品時間比較集中的放入快取,假設快取過期時間是一個小時,那麼1個小時後,這批商品的快取都獲取了,而對這波商品的訪問查詢,都落到了資料庫上,對於資料庫而言,就會產生週期性的壓力波峰。於是所有的請求都會到達儲存層,儲存層的呼叫量暴增,造成儲存層可能掛掉的情況。
在這裡插入圖片描述
解決方案
redis高可用
這個思想的含義是,既然redis有可能掛掉,那就增加幾臺redis,這樣1臺掛掉還有其他的可以繼續工作,就是搭建redis叢集(解決redis當機引起的快取雪崩問題),可以使用異地多活。
限流降級(SpringCloud中有限流降級解決方案,停掉某些服務,保證主業務可用)
這個解決方案的思想是,在快取失效後,通過加鎖或者佇列來控制讀資料庫寫快取的執行緒數量,比如對某個Key只允許一個執行緒查詢資料和寫快取,其他執行緒等待。
資料預熱
資料預熱的含義就是在正式部署之前,我先把可能的資料先預先訪問一遍,這樣部分可能大量訪問的資料就會載入到快取中。在即將發生大併發訪問前手動觸發載入快取不同的key,設定不同的過期時間,讓快取失效的時間點儘量均勻(解決因為快取集中過期而引起的快取雪崩問題)。

參考連結

https://www.bilibili.com/video/BV1S54y1R7SB?p=36

相關文章