前言
如何有效的理解並且區分 Reids 穿透、擊穿和雪崩之間的區別,一直以來都挺困擾我的。特別是穿透和擊穿,過一段時間就稀裡糊塗的分不清了。
為了有效的幫助筆者自己,以及擁有同樣煩惱的朋友們區分這三種場景。筆者總結了一些關鍵詞
,希望大家可以和我一樣通過聯想的方式來區分並理解這三種場景的區別!
快取穿透:
關鍵詞:穿過 Redis 和 資料庫
當 Redis 和資料庫中都沒有我們想要的資料時,就需要考慮快取穿透的問題了
下面這段邏輯大家用的會比較多:先去 Redis 中查詢某資源,Redis 中查不到就去 DB 中查,DB 中查到後回寫一份資料到 Redis 中。
這段邏輯正常情況下問題並不大,但是如果使用者惡意重複請求資源 X,該資源在 Redis 和 DB 中都不存在。那麼每次請求都會直接打到 DB 上,甚至導致物理 DB 當機。
解決方案:
1、快取空結果
如果系統發現 Redis 及 DB 中都不存在該資源,就快取空結果一段時間。需要注意哈,這次的失效時間不能設定的太長,否則資料的實效性會產生很大的問題。
2、使用者合法性校驗
對使用者的請求合法性進行校驗,攔截惡意重複請求
3、布隆過濾器
看到這個名詞不要慌。簡單來說布隆過濾器的用途就是幫助你判斷某個值是否存在。
舉個例子來看下: 假設我們現在有一個長度為 9 的 bit 陣列,該陣列的每個位置上只能儲存 1 或者 0,1 標識該位置被佔用,0 標識該位置未被使用。
對於 key1,我們藉助三個 Hash 函式分別對其雜湊運算 再將得到的這三個雜湊值對 9 求模。 最後將這三個模值落入到 bit 陣列上。 key2、key3 按照同樣的方式再處理一遍。
key值 | 模值 |
---|---|
key1 | 1、4、6 |
key2 | 2、5、7 |
key3 | 6、8、9 |
最後,我們會發現這個 bit 陣列裡只有位置 3 還是空著的。如果此時來了一個新的 key4 通過三個Hash演算法求出的雜湊值為 1、2、3,我們則可以斷定 key4 一定不存在。
布隆過濾器的原理還是比較簡單的。這裡我們需要注意,布隆過濾器可能存在一定誤判的可能性,但它依然可以幫助你攔截掉大部分一定不存在的資料。
快取擊穿
關鍵詞:定點打擊
試想如果所有請求對著一個 key 照死裡搞,這是不是就是一種定點打擊呢?
怎麼理解呢?舉個極端的例子:比如某某明星爆出一個驚天狠料,海量吃瓜群眾同時訪問微博去檢視該八卦新聞,而微博 Redis 叢集中資料在此刻正好過期了,那麼無數的請求則直接打到了微博系統的物理 DB 上,DB 瞬間掛了。
解決方案:
1、熱點資料永遠不過期
比如我們可以將某個 key 的快取時間設定為 25 小時,然後後臺有個 JOB 每隔 24 小時就去批量重新整理一下熱點資料。就可以解決這個問題了
2、使用互斥鎖
容易影響吞吐量,大部分專案設定熱點 key 永不過期就妥妥的了
快取雪崩
關鍵詞:Redis 崩了,沒有資料了
這裡的 Redis 崩了指的並不是 Redis 叢集當機了。而是說在某個時刻 Redis 叢集中的熱點 key 都失效了。
如果叢集中的熱點 key 在某一時刻同時失效了的話,試想海量的請求都將直接打到 DB 上,DB 可能在瞬間就被打爆了。
解決方案
1、Redis 失效時間加上隨機數
Redis 失效時間加上隨機數,是一種比較取巧的解決方案。在一定程度上減輕了 DB 的瞬時壓力,但是這種方案也在一定程度上增加了維護的成本。
2、Redis 永不過期
實現方案在上文中簡單提過了
總結
最後我們再回歸到主題!
如何輕鬆的通過聯想的方式來區分 Redis 快取穿透、擊穿、雪崩的區別
快取穿透---穿過(繞過) Redis 和 DB 來搞你
快取擊穿---定點打擊來搞你
快取雪崩---熱點 key 在某一個時刻同時失效