溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發(fā)布時間:2023-03-29 11:28:14 來源:億速云 閱讀:93 作者:iii 欄目:開發(fā)技術

本篇內容介紹了“Redis緩存擊穿、緩存穿透、緩存雪崩如何解決”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

Redis緩存使用場景

Redis會把數(shù)據庫中經常被查詢的數(shù)據緩存起來,比如熱點數(shù)據,這樣當用戶通過網站或APP來訪問的時候,就不需要到數(shù)據庫中去查詢了,而是直接獲取 Redis中的緩存數(shù)據,從而降低了后端數(shù)據庫的讀取壓力。如果說用戶查詢的數(shù)據Redis中沒有,此時用戶的查詢請求就會轉到數(shù)據庫,當數(shù)據庫將數(shù)據返回給客戶端時,同時會將數(shù)據緩存到 Redis中,這樣用戶再次讀取時,就可以直接從Redis中獲取數(shù)據。流程圖如下所示:

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

Redis緩存穿透

緩存穿透是指用戶惡意的發(fā)起大量請求去查詢一個緩存(Redis)和數(shù)據庫(DB)中都沒有的數(shù)據,出于容錯考慮從數(shù)據庫(DB)查不到數(shù)據則不寫入緩存(Redis)這將導致每個請求都要到數(shù)據庫(DB)中查詢,失去了緩存的意義,從而導致數(shù)據庫因壓力過大掛掉。

流程圖如下所示:

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

解決方案

1.對空值緩存

上面我們也介紹了,之所以會發(fā)生穿透,是因為緩存中沒有存儲這些空數(shù)據的key,從而導致每次查詢都到數(shù)據庫去了。

那么我們就可以為這些key的值設置null丟到緩存里面去,后面再出現(xiàn)查詢這個key 的請求的時候,直接返回null ,就不用在到數(shù)據庫中去走一圈了。但是別忘了設置過期時間。

關鍵代碼如下:

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

2.添加參數(shù)校驗

我們可以在接口層添加校驗,不合法的直接返回即可,沒必要做后續(xù)的操作。

例如:使用bitmaps類型定義一個可以訪問名單,名單id作為bitmaps的偏移量,每次訪問時與bitmaps中的id進行比較,如果訪問id不在bitmaps中,則進行攔截,不給其訪問。

3.采用布隆過濾器

布隆過濾器(Bloom Filter),Bloom Filter 類似于一個hash set 用來判斷某個元素(key)是否存在于某個集合中,不存在return就好了,存在就去查DB刷新緩存KV再return,它的優(yōu)點是空間效率和查詢時間都比一般算法快,缺點是有一定的誤識別率和刪除困難。

布隆過濾器的工作方式:

一個空的布隆過濾器是一個由m個二進制位構成的數(shù)組。

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

以上只是畫了布隆過濾器的很小很小的一部分,實際布隆過濾器是非常大的數(shù)組(這里的大是指它的長度大,并不是指它所占的內存空間大)。

當一個數(shù)據進行存入布隆過濾器的時候,會經過若干個哈希函數(shù)進行哈希,得到對應的哈希值作為數(shù)組的下標,然后將初始化的位數(shù)組對應的下標的值修改為1,結果圖如下:

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

當再次進行存入第二個值的時候,修改后的結果的原理圖如下:

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

那么為什么會有誤判率呢?

假設在我們多次存入值后,在布隆過濾器中存在x、y、z這三個值,布隆過濾器的存儲結構圖如下所示:

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

當我們要查詢的時候,比如查詢M這個數(shù),實際中M這個數(shù)是不存在布隆過濾器中的,經過哈希函數(shù)計算后得到M的哈希值分別為1和7,結構原理圖如下:

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

經過查詢后,發(fā)現(xiàn)1和7位置所存儲的值都為1,但是1和7的下標分別是X和Z經過計算后的下標位置的修改,該布隆過濾器中實際不存在M,那么布隆過濾器就會誤判改值可能存在,因為布隆過濾器不存元素值,所以存在誤判率。

那么為什么不能刪除元素呢?

原因很簡單,因為刪除元素后,將對應元素的下標設置為零,可能別的元素的下標也引用改下標,這樣別的元素的判斷就會受到影響。

Redis緩存雪崩

緩存雪崩是指大量的應用請求無法在Redis緩存中進行處理,緊接著應用將大量請求發(fā)送到數(shù)據庫層,導致數(shù)據庫層的壓力激增。

緩存雪崩一般是由兩個原因導致的,應對方案也有所不同。第一個原因是:緩存中有大量數(shù)據同時過期,導致大量請求無法得到處理。第二個原因是:Redis 緩存實例發(fā)生故障宕機了,無法處理請求,這就會導致大量請求一下子積壓到數(shù)據庫層,從而發(fā)生緩存雪崩。

流程圖如下所示:

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

解決方案

1.大量熱點數(shù)據同時失效帶來的緩存雪崩問題

避免熱key同時失效

使用 EXPIRE命令給每個數(shù)據設置過期時間時,給這些數(shù)據的過期時間增加一個較小的隨機數(shù)(例如,隨機增加 1~3 分鐘)。這樣一來,不同數(shù)據的過期時間有所差別,但差別又不會太大。既避免了大量數(shù)據同時過期,同時也保證了這些數(shù)據基本在相近的時間失效,仍然能滿足業(yè)務需求。

2. 服務降級

所謂的服務降級,是指發(fā)生緩存雪崩時,針對不同的數(shù)據采取不同的處理方式,例如:

當業(yè)務應用訪問的是非核心數(shù)據時,暫時停止從緩存中查詢這些數(shù)據,而是直接返回預定義信息、空值或是錯誤信息;

當業(yè)務應用訪問的是核心數(shù)據時,仍然允許查詢緩存,如果緩存缺失,也可以繼續(xù)通過數(shù)據庫讀取。

這樣一來,我們就避免了大量請求因緩存缺失,而積壓到數(shù)據庫系統(tǒng),保證了數(shù)據庫系統(tǒng)的正常運行。

3. Redis 緩存實例發(fā)生故障宕機帶來的緩存雪崩問題

從事前預防的角度,我們可以通過主從節(jié)點的方式構建 Redis 緩存高可靠集群。如果 Redis緩存的主節(jié)點故障宕機了,從節(jié)點還可以切換成為主節(jié)點,繼續(xù)提供緩存服務,避免了由于緩存實例宕機而導致的緩存雪崩問題。

如果實際業(yè)務系統(tǒng)真發(fā)生了Redis 緩存實例不可用的情況,我們可以在業(yè)務系統(tǒng)中實現(xiàn)服務熔斷或請求限流機制。所謂的服務熔斷,是指在發(fā)生緩存雪崩時,為了防止引發(fā)連鎖的數(shù)據庫雪崩,甚至是整個系統(tǒng)的崩潰,我們暫停業(yè)務應用對緩存系統(tǒng)的接口訪問。

Redis緩存擊穿

我們在平常高并發(fā)的系統(tǒng)中,大量的請求同時查詢一個key時,假設此時這個key正好失效了,就會導致大量的請求都打到數(shù)據庫上面去,這種現(xiàn)象我們稱為擊穿。

這么看緩存擊穿和緩存雪崩有點像,但是又有一點不一樣,緩存雪崩是因為大面積的緩存失效,打崩了DB,而緩存擊穿不同的是「緩存擊穿」是指一個Key非常熱點,在不停的扛著大并發(fā),大并發(fā)集中對這一個點進行訪問,當這個Key在失效的瞬間,持續(xù)的大并發(fā)就穿破緩存,直接請求數(shù)據庫,就像在一個完好無損的桶上鑿開了一個洞,如下圖所示:

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

解決方案

1. 熱key不過期

預先設置熱門數(shù)據:在Redis高峰訪問時期,提前設置熱門數(shù)據到緩存中,對這些熱key不設置失效時間,不過這樣設置需要區(qū)分場景。

實時調整:實時監(jiān)控哪些數(shù)據熱門,實時調整key過期時間。

2. 分布式鎖

為了避免出現(xiàn)緩存擊穿的情況,我們可以在第一個請求去查詢數(shù)據庫的時候對他加一個分布式鎖,其余的查詢請求都會被阻塞住,直到鎖被釋放,后面的線程進來發(fā)現(xiàn)已經有緩存了,就直接走緩存,從而保護數(shù)據庫。但是也是由于它會阻塞其他的線程,此時系統(tǒng)吞吐量會下降。需要結合實際的業(yè)務去考慮是否要這么做。

關鍵代碼如下:

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

總結

緩存擊穿

key對應的數(shù)據存在,但在redis中過期,此時若有大量并發(fā)請求過來,這些請求發(fā)現(xiàn)緩存過期一般都會從后端DB加載數(shù)據并回設到緩存,這個時候大并發(fā)的請求可能會瞬間把后端DB壓垮。一般通過互斥鎖,熱點數(shù)據永不過期,定時刷新過期時間等方法解決該問題。

緩存穿透

key對應的數(shù)據在數(shù)據源并不存在,每次針對此key的請求從緩存獲取不到,請求都會到數(shù)據源,從而可能壓垮數(shù)據源。比如用一個不存在的用戶id獲取用戶信息,不論緩存還是數(shù)據庫都沒有,若黑客利用此漏洞進行攻擊可能壓垮數(shù)據庫。一般通過對空數(shù)據進行緩存,布隆過濾器等方法解決該問題。

緩存雪崩

當緩存服務器重啟或者大量緩存集中在某一個時間段失效,這樣在失效的時候,也會給后端系統(tǒng)(比如DB)帶來很大壓力。一般通過加鎖排隊,設置過期時間隨機值等方法解決該問題。

“Redis緩存擊穿、緩存穿透、緩存雪崩如何解決”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI