天天看點

Redis 面試常見問題———緩存雪崩、緩存擊穿以及緩存穿透

在開發中會面臨緩存異常可能會出現三個問題,分别是緩存雪崩、緩存擊穿和緩存穿透。這三個問題會導緻大量請求從緩存轉移到資料庫,如果請求的并發量很大的話,就會導緻資料庫崩潰。是以在面試官也會經常問這些問題。

緩存雪崩是指大量的請求無法在緩存中處理,進而将請求轉移到資料庫中,導緻資料壓力倍增。一個Redis執行個體可以支援萬級别的并發請求,而單個資料庫隻能支援千級别的并發請求。兩者處理請求并發能力相差十倍,資料庫會由于壓力過大而導緻雪崩。

這裡雪崩一般是由兩個原因組成,很多文章隻寫緩存同時過期的情況。

Redis 面試常見問題———緩存雪崩、緩存擊穿以及緩存穿透

一般設定緩存資料會設定緩存時間,在某一時刻,大量的緩存同時過期,此時如果有請求通路這些資料的話,緩存不存在,會将請求轉移到資料庫,如果這些的請求量比較大的,導緻資料庫的壓力增大,嚴重會導緻資料庫崩潰。

針對大量緩存同時失效帶來的雪崩,有兩種解決方案。

應該避免給資料設定相同的過期時間,在設定過期時間時,增加一點随機值。

服務降低,比如使用hystrix,是指發生雪崩時,針對不同的資料采取不同的處理方式。

請求資料是非核心資料(比如商品屬性),暫時停止從緩存查詢資料,直接傳回預定資訊、空值或者錯誤值。

請求資料是核心資料(比如商品庫存、價格),仍然查詢緩存,如果緩存缺失,繼續在資料庫讀取。

Redis 面試常見問題———緩存雪崩、緩存擊穿以及緩存穿透

redis服務發生當機,無法處理請求,這就會導緻全部轉移到資料庫去,發生雪崩。

服務熔斷,就是發生雪崩時,暫停對緩存的通路。等redis服務恢複正常後,再允許通路緩存。

對redis所在的伺服器進行名額監控,比如QPS、CPU使用率、記憶體使用率等,如果發現redis服務當機,而資料庫請求壓力倍增,此時可以啟動熔斷機制,暫停對緩存和資料庫的通路,比如使用Hystrix服務熔斷。

但是暫停對緩存系統的通路,但是對整個業務系統影響很大,導緻很多資料不能檢視。為了減少這種影響還有另一個方案:請求限流。

請求限流,就是限制前端請求每秒請求量,使得資料庫能承受前端全部請求。

比如前端允許每秒通路1000次,其中900請求緩存,100次才請求資料庫。

一旦發生雪崩,資料庫每秒請求激增到1000次,此時啟動請求限流,在前端入口隻允許每秒請求100次,過多的請求直接拒絕。

Redis 面試常見問題———緩存雪崩、緩存擊穿以及緩存穿透

無論使用服務熔斷或請求限流都是是發生雪崩後處理,這裡還有事先預防的方案。

通過主從節點的方式建構redis叢集,如果redis主節點當機,從節點可以切換成主節點。

緩存擊穿是指,針對某個通路緩存非常頻繁,無法在緩存中處理,通路該資料的請求一下子都請求資料庫,導緻資料庫壓力倍增。

Redis 面試常見問題———緩存雪崩、緩存擊穿以及緩存穿透

對于通路特别頻繁的熱點資料,就不設定過期時間

如果緩存失效,隻有拿到鎖才能通路資料庫,降低資料庫并發通路。

緩存雪崩和緩存擊穿的差别在于雪崩是大量的緩存,擊穿是單一的緩存。

緩存穿透是指通路的資料既不在redis緩存中,也不在資料庫中,因為資料庫也不存在資料,也無法将資料庫資料寫入緩存中,每次請求都要請求緩存和伺服器。不過這樣也導緻系統性能下降。

緩存穿透會發生如下兩種情況:

誤操作,删除了緩存和資料的資料。

惡意攻擊: 專門通路資料庫中不存在的資料。

Redis 面試常見問題———緩存雪崩、緩存擊穿以及緩存穿透

發生緩存穿透,在redis中緩存一個空值或者實作預選設定好的值(比如0),後續請求查詢直接在redis中讀取空值或者預設值。

布隆過濾器由一個初值都為0的bit數組和N個哈希函數組成,可以用來快速判斷某個資料是否存在。當資料寫入資料庫時,布隆過濾器會通過三個操作完成标記:

使用N個hash函數,分别計算這個資料的hash值,得到N個hash值。

把這N個hash值對bit數組的長度取模,得到每個hash值在數組中對位置。

把對應位置設定為1。如果資料不存在,那麼就沒用使用布隆過濾器标記過資料,那麼,bit數組對應的bit位為零。隻要bit數組有一個不為1,就表明布隆過濾器就沒标記過該資料。

把資料寫入資料庫時,使用布隆過濾器做标記

當緩存消失後,在去資料庫查詢之前,通過查詢布隆過濾器判斷資料是否存在,如果不存在,就不查詢資料庫。

還有在請求入庫添加檢測,把惡意請求(參數不合理、參數非法、參數不存在或者id小于0)直接過濾掉。

緩存雪崩

* 電商首頁資料(電腦端、手機端),比如分類。設定這一類的緩存需要給過期時間添加随機數

Redis 面試常見問題———緩存雪崩、緩存擊穿以及緩存穿透

緩存擊穿

電商首頁的猜你喜歡商品,不設定逾時時間,或者設定互斥鎖

Redis 面試常見問題———緩存雪崩、緩存擊穿以及緩存穿透

緩存穿透

電商商品詳情中請求不存在的id,首先要設定入口驗證,然後使用布隆過濾器,不存在直接傳回

緩存雪崩和緩存擊穿主要是資料不在緩存上,而緩存穿透是資料既不在緩存上,也不在資料上。

給過期時間加上小的随機數

服務降級

服務熔斷

請求限流

redis 設定主從叢集

不設定過期時間

入口進行合法性驗證

使用空值或者預設值

使用布隆過濾器快速判斷

使用服務降低、請求熔斷、請求限制會影響使用者使用體驗,最好使用預防方案。

針對緩存雪崩,合理設定資料過期時間,以及搭建redis主從叢集。

針對緩存擊穿,不要設定過期時間。

針對緩存穿透,在請求入口做規範校驗,以及使用布隆過濾器判斷資料是否存在。

如何解決緩存雪崩、擊穿、穿透難題