1. 程式人生 > 其它 >Redis快取穿透和雪崩(面試高頻、工作常用)

Redis快取穿透和雪崩(面試高頻、工作常用)

Redis快取穿透和雪崩(面試高頻、工作常用)

Redis快取使用流程

客戶端向伺服器傳送讀請求,此時後臺會先去快取中查資料,如果資料命中,那麼返回結果,反之去資料庫中查詢,如果資料庫中查到資料,那麼返回資料,並且寫入快取,如果沒有查到該資料即返回空結果

快取穿透(資料未命中)

概念

快取穿透的概念很簡單,使用者想要查詢一個數據,發現Redis快取中沒有,也就是快取沒有命中,於是就向資料庫查詢,然後發現也沒有,於是本次查詢失敗。當用戶很多的時候(秒殺場景),如果在快取都沒有命中,於是都去請求了資料庫DB,一瞬間就給資料庫造成巨大的壓力,這種情況就是常說的快取穿透。

解決方案(這裡簡單介紹、具體過程後面學習了更新)

1、布隆過濾器

布隆過濾器是一種資料結構,對所有可能查詢的引數以hash形式儲存,在控制層先進行校驗,不符合則丟棄,從而避免了對底層儲存系統的查詢壓力。

2、快取空物件

當儲存層不命中時,即使返回的空物件也將其快取起來,同時會設定一個過期時間,之後再訪問這個資料將會從快取中獲取,從而保護了後端資料來源。

但是這種方式存在兩個問題:

  • 如果空值能夠被快取起來,這就意味著需要更多的空間儲存更多的鍵,因為其中可能會有很多空值的鍵。
  • 即使對空值設定了過期時間,還是會存在快取層和儲存層的資料會有一段時間視窗不一致的問題,這對於需要保持一致的業務會有影響。

快取擊穿(熱點key失效,大量資料集中於一點)

概述

這裡和快取穿透不同,快取穿透是查詢不到資料,所以都去查詢資料庫,給資料庫造成很大壓力;而快取擊穿是一個key十分熱點(比如微博某明星熱搜),快取在不停地抗著高併發,始終對一個點訪問,當這個快取資料失效後,大量的高併發請求穿破快取,在很短時間去請求資料庫(就好比一梭子子彈打容器上),就像在螢幕中鑿了個洞。

當這個熱點key失效過期後,大量併發請求前往資料庫查詢最新資料,查詢完後並寫入快取,會使資料庫壓力過大。

解決方案

1、設定熱點資料永不過期
從快取層面來看,沒有設定過期時間,所以不會出現熱點key過期後產生的問題。

2、加互斥鎖
分散式鎖:使用分散式鎖,保證對每個key同時只有一個執行緒去查詢後端服務,其它執行緒沒有獲得分散式鎖的許可權,因此只需要等待即可。這種方式將高併發的壓力轉移到了分散式鎖,因此對分散式鎖的考驗很大。

快取雪崩(大量的key幾乎同時過期)

概述

快取雪崩是因為大面積的快取在一個時間點集中失效,打崩了資料庫。

舉個簡單的例子:如果所有首頁的Key失效時間都是12小時,中午12點重新整理的,在零點的時候有個秒殺活動會有大量使用者湧入,假設當時每秒 6000 個請求,本來快取在可以扛住每秒 5000 個請求,但是這個時候快取所有的Key都失效了。此時 1 秒 6000 個請求全部落資料庫,資料庫必然扛不住,它會報一下警,真實情況可能DBA(管理員)都沒反應過來就直接掛了。此時,如果沒用什麼特別的方案來處理這個故障,DBA 很著急,重啟資料庫,但是資料庫立馬又被新的流量給打死了。這就是快取雪崩。

解決方案

1、Redis高可用
這個思想的含義就是:既然Redis有可能會掛掉,那我多增設幾臺Redis,這樣一臺掛掉了之後其它的還可以繼續工作,高可用其實就是搭建的Redis叢集。將熱點資料均勻分佈在不同的Redis庫中。

2、限流降級
這個解決方案的思想就是:在快取失效後,通過加鎖或者佇列來控制讀資料庫寫快取的執行緒數量。比如對某個key只允許一個執行緒查詢資料和寫快取,其它執行緒等待。

3、資料預熱
資料預熱的含義就是在正式部署之前,先把可能高訪問的資料預先訪問一遍,這樣可能大部分的資料就能載入到快取中。在即將發生大併發訪問前手動觸發載入快取中不同的key,設定不同的過期時間,讓快取失效的時間點儘量均勻一點。

4、在批量往Redis存資料的時候,把每個key的失效時間都加個隨機值,這樣保證資料不會在同一時間大面積失效。