快取穿透 快取擊穿 快取雪崩詳解

2021-10-24 17:38:27 字數 2911 閱讀 2302

redis 在專案中用的話,主要就是用作快取了

既然用作快取,那就肯定會有 快取穿透/快取擊穿/快取雪崩 的問題

這篇文章就來說說,遇到這種情況時,該如何去處理

首先咱們搞明白什麼是快取穿透?這三個詞這麼像,得把概念搞清楚不是

其實只是從字面意思上來看的話,大概也能知道一點兒,快取穿透嘛,就是直接穿過了快取,將請求打到了資料庫上面去

一般情況下,去查詢資料的話,快取裡面應該都是有的,但是防不住黑客呀,如果黑客請求查詢的是資料庫裡面根本不存在的資料,資料庫裡面都沒有的資料,快取裡面肯定也不會有了,對吧,那麼此時請求就會打到咱們的資料庫裡面去,這就是快取穿透

你想啊,黑客想要攻擊的話,怎麼可能只請求一次呢,肯定是大量的請求過來,因為是拿資料庫裡面不存在的 id 來請求的,那麼這些請求毫無疑問直接打到了資料庫上面去,那咱們的資料庫可能就會因為這些大量的請求直接宕掉

如何解決呢?

咱們回到產生這個問題的場景中,為什麼大量的請求會打到資料庫上面來?因為快取裡面沒有對應的 key 對吧,所以才會越過快取直接到資料庫

那麼問題就好解決了嘛,快取裡面沒有對應的 key ?ok ,如果這個 key 資料庫裡面也沒有,那我就在 redis 裡面,存上這個 key ,值是 null ,這樣如果有查詢這個 key 的請求,我直接返回 null 就完事兒了,也就不用打到資料庫上面去了

注意一下,要記得設定它的過期時間,一般三到五分鐘就夠了

但是對方是個黑客呀,可能就用乙個 key 去請求麼?他可能會在短時間內用大量的 key 來傳送請求,那如果乙個 key 就在 redis 中儲存乙個 null 值的話,那麼多 key 是不是就會儲存那麼多個 null 值嘞?

這樣的話, redis 裡面是不是都是值為 null 的了?

所以有沒有更好的解決辦法呢?

那必須得有!布隆過濾器,你值得嘗試

什麼是布隆過濾器呢?就是它能告訴你,某個值一定不存在或者可能存在( emmmm ,也不知道我有沒有說清楚

所以可以將資料庫的內容快取乙份到布隆過濾器,這樣的話,當大量的請求過來的時候, redis 裡面沒有,沒關係,再去布隆過濾器過濾一下,這樣請求不用打到資料庫上面去,就能確定這個 key 資料庫中有沒有

這樣不就降低了資料庫的壓力麼,可真是個天才~

快取擊穿說的是,在高併發情況下,如果好多個請求都在查詢乙個 key ,好巧不巧的是,這個 key 因為某些原因失效了(比如設定的過期時間到了,快取伺服器宕機了),這樣就會導致那麼多的請求都直接打到資料庫上面去了

那如果這些請求的數量足夠大的話,可能直接把資料庫就乾掉了

知道了造成結果的原因,那麼尋找解決方案也就好辦了

不是因為好多個請求打到了資料庫嘛,但是它們請求的都只是乙個 key ,所以這裡可以使用排斥鎖來實現,第乙個請求達到請求 key 發現快取裡面沒有,允許它去資料庫查詢,同時加鎖,這樣第二個請求,第三個請求…都會被鎖阻塞到當前,不會再打到資料庫,這樣就減少了資料庫的併發壓力

快取雪崩,雪崩雪崩嘛,就比較嚴重,擊穿說的是乙個 key 失效的情況,雪崩指的是大規模的快取失效情況的發生,這是有可能發生的,比如說我的快取伺服器宕機了,那是不是直接就大規模的快取失效了;或者說,我當時為了圖省事,好多個 key 設定的過期時間都是一樣的,然後剛好在快取都失效的時候,好多請求不同的 key 過來了

解決方案的話,其實就不適合使用加鎖的方式去解決了,因為這是好多請求不同的 key ,它不是乙個嘛

而且嘞,咱們是因為好多個 key 設定的過期時間都是一樣的,所以解決方案就是,咱們不設定同樣的時間讓快取失效了,咱們給乙個隨機時間,讓快取隨機失效,這樣的話,大規模的快取失效情況就減少很多了

那還要一種情況呢,就是如果我的快取伺服器直接宕機了,這怎麼辦?也好弄,來個集群就解決了,這裡只是乙個解決方案,它的落地實現不是本文重點哈~

ok ,你如果看到這裡的話,其實這篇文章的內容就說完了

但是我感覺布隆過濾器那塊,我沒有說清楚,所以在這裡拿出來詳細說一說

布隆過濾器是一種資料結構,它是一種概率型的資料結構,就是它能告訴你「某樣東西一定不存在或者可能存在」

你可能會說,這話剛剛不是說過了嘛,本來就挺拗口的,你咋還說

還不是因為這句話比較重要,我覺得把這句話理解透徹了,那麼對布隆過濾器理解的應該也就到位了

來,為了形象生動一些,咱們舉個例子~ 布隆過濾器是乙個 bit 向量或者說 bit 陣列,大概長這樣:

現在,我們需要把 「alipay」 這個欄位給儲存進去 大概的儲存過程就是:將要對映的值,使用多個不同的雜湊函式生成多個雜湊值,然後每個生成的雜湊值指向的 bit 置為 1

以給的為例,我們現在將 「alipay」 這個值,通過三個不同的雜湊函式進行對映,那麼大概就是這樣了:

同樣,現在我要儲存另外乙個值 「wechatpay」 ,那麼可能對映之後就是下面這樣:

細心的你可能就會發現, 4 號位置的值,剛開始不是給 「alipay」 了麼,後來 「wechatpay」 也在那裡,這樣的話,值不就給覆蓋掉了嘛

嗯,沒錯,是被覆蓋掉了

接下來,我們查詢 「ali」 那麼查詢之後,布隆過濾器可能會給你 「0,1,2」 的值, 結果呢 「2」 的位置是 0 ,說明沒有任何值對映到這個位置上來,所以我們就可以判定資料庫裡面沒有 「ali」 這個值

那我查詢 「alipay」 的話,毫無疑問,肯定會返回給我 「1,4,6」 ,那我們能說資料庫裡面一定有 「alipay」 麼?不能,因為 「1,4,6」 的值有可能被其他的值給覆蓋到了,所以我們只能說,資料庫裡可能存在 「alipay」

這就是布隆過濾器說的"某個值一定不存在或者可能存在"

乖,你懂了嗎?

快取穿透 快取擊穿 快取雪崩

一 快取處理流程 前台請求,後台先從快取中取資料,取到直接返回結果,取不到時從資料庫中取,資料庫取到更新快取,並返回結果,資料庫也沒取到,那直接返回空結果。二 快取穿透 描述 快取穿透是指快取和資料庫中都沒有的資料,而使用者不斷發起請求,如發起為id為 1 的資料或id為特別大不存在的資料。這時的使...

快取穿透,快取擊穿,快取雪崩

所謂的快取穿透,簡單來講就是查詢某些不存在的key時,快取和資料庫查詢結果都為空,而空的結果又不被快取起來,而導致每次查詢都去請求資料庫層的情況。在流量大時,可能db就掛掉了,要是有人利用不存在的key頻繁攻擊我們的應用,這就是漏洞。過程 快取不命中,進而導致每次查詢都去查詢資料庫,快取也就失去了作...

快取穿透快取擊穿快取雪崩

1 快取穿透 1.1 什麼是快取穿透 快取穿透,是指查詢乙個資料庫一定不存在的資料 核心 快取和資料庫該值不存在 正常的使用快取流程大致是,資料查詢先進行快取查詢,如果key不存在或者key已經過期,再對資料庫進行查詢,並把查詢到的物件,放進快取。如果資料庫查詢物件為空,則不放進快取。1.2 帶來的...