一文搞懂redis快取雪崩、快取擊穿和快取穿透

2022-11-14 18:02:13
本篇文章給大家帶來了關於的相關知識,其中主要介紹了關於快取雪崩、快取擊穿和快取穿透的相關內容,下面一起來看一下,希望對大家有幫助。

千萬級資料並行如何處理?進入學習

推薦學習:

關於Redis的高頻問題,快取雪崩、快取擊穿和快取穿透一定少不了,相信大家在面試中都被問到過類似的問題。為什麼這些問題一直熱門呢?因為我們在使用Redis快取時,這些問題都是很容易遇到的。接下來我們就來看看這些問題都是怎麼產生的,對應的解決方案都有哪些吧。

快取雪崩

首先來看看快取雪崩,快取雪崩的概念就是:大量的請求沒有在Redis快取中得到處理,從而導致請求都湧入到資料庫中,然後資料庫的壓力劇增。

引起快取雪崩的原因可總結為2個:

  • 快取中有大量的資料同時過期,這樣此時大量的請求都懟到資料庫了。
  • Redis快取範例發生故障了,無法處理大量請求,也會導致請求都跑到資料庫去了。

先來看看第一個場景:快取中大量的資料同時過期問題。

快取中大量的資料同時過期

結合圖例來看,就是大量的資料在同一時間過期,然後此時又有很多的請求要讀取這些資料。當然就會發生快取雪崩,從而導致資料庫壓力劇增了。

大量資料同時過期的解決方案

應對大量資料同時過期問題,通常有2種方案:

  • 資料過期設定增加隨機時間:也就是用expire命令給資料設定過期時間時,增加一個隨機的時間,比如資料a是5分鐘過期,在5分鐘的基礎上隨機增加10-120秒時間。這樣就能避免大量資料同時過期。
  • 服務降級:也就是發生快取雪崩時,(1)若存取的不是核心資料,當沒有快取命中時,不去資料庫了,直接返回預先設定好的資訊,比如空值或者錯誤資訊;(2)當存取的是核心資料,快取未命中時,允許去資料庫查詢。這樣就將不是核心資料的請求都拒絕懟到資料庫了。

看完了大量資料同時過期的情況,再來看看Redis快取範例故障的情況。

Redis快取範例故障導致的快取雪崩

這種情況下,Redis無法處理讀請求了,請求自然就懟到資料庫了。

通常來說,應對這種情況,我們也有2種方式:

  • 在業務系統中做好服務熔斷/請求限流
  • 事前預防:構建Redis高可靠叢集,比如主從叢集的主備切換。

服務熔斷,也就是當Redis發生故障時,暫停請求對快取系統的存取。等到Redis恢復正常了再開啟請求存取。

這種方式我們需要對Redis或資料庫的執行狀態進行監控,比如MySQL的負載壓力、Redis的CPU使用率、記憶體使用率及QPS等。當發現Redis範例快取雪崩了,就暫停服務。

這種情況能有效放置大量請求對資料庫造成壓力。但是會暫停請求存取,對業務端的影響很大。

因此,為了減少對業務端的影響,我們可以使用請求限流方式,控制QPS,避免過多的請求懟到資料庫去。比如下面圖例,本身有2萬每秒的請求,但因為Redis故障宕機了。我們限流操作將qps降到2千每秒,資料庫處理2000的qps還是沒問題的。

快取擊穿

快取擊穿就是指個別存取頻繁的熱點資料無法快取命中,然後請求都湧入到資料庫中。它經常會在熱點資料過期時發生。

對於快取擊穿問題,我們知道這些都是被存取非常頻繁的熱點資料,處理方式就簡單粗暴了,直接不設定過期時間了。等熱點資料不頻繁存取再手動處理即可。

快取穿透

快取雪崩有些特別,它是指要存取的資料既不在Redis快取,也不在資料庫中。當大量請求進到系統時,Redis和資料庫都會有巨大壓力。

導致快取穿透的原因通常有2種:

  • 資料被誤刪除了,導致快取和資料庫都沒有資料了。然而使用者端是不知道的,還在瘋狂請求。
  • 有惡意攻擊的情況:也就是被人盯上了,專門去查沒有的資料。

對於快取穿透的情況,解決方案可以參考下面幾種:

  • 是對快取設定空值或者預設值。 比如發生快取穿透時,在Redis快取中設定空值/預設值。後續查詢該值時就直接返回這個預設值了。
  • 使用布隆過濾器來判斷資料是否存在,避免從資料庫查詢。
  • 在前端就進行請求檢測。 比如在前端將一些不合法的請求直接過濾,不要發到後端來處理。

第一點和第三點比較容易理解,這裡就不展開描述。我們重點來看看第二點:布隆過濾器。

布隆過濾器

布隆過濾器主要用於判斷一個元素是否在一個集合中。它是由一個固定大小的二進位制向量(可理解成預設為0的bit陣列)和一系列的對映函陣列成的。

我們首先來看看布隆過濾器是如何標記一個資料a的:

  • 第一步,會使用到多個對映函數(雜湊函數),每個函數都會計算這個資料a的雜湊值;
  • 第二步,這些計算得出的雜湊值會分別對bit陣列長度取模,這樣就得到每個雜湊值在陣列上的位置;
  • 第三步,把第二步得到的位置,分別在bit陣列上設定為1。

通過這3個步驟,資料標記就完成了。然後要查詢資料在不在的時候是這樣做的:

  • 先計算這個資料在bit陣列中的多個位置;
  • 然後分別檢視bit陣列的這些位置的bit值。只有每個位置的bit值都為1,說明資料才可能存在,否則資料一定不存在。

結合下圖來看,基本原理就是這樣。

image.png

推薦學習:

以上就是一文搞懂redis快取雪崩、快取擊穿和快取穿透的詳細內容,更多請關注TW511.COM其它相關文章!