緩存穿透詳解及解決方案

  • 2022 年 2 月 17 日
  • 筆記

當存儲系統成為瓶頸時,比如高並發、讀多寫少等場景,我們首先會想到的就是利用緩存來提高整個系統的性能。

緩存雖然能夠大大提升整個系統的性能,但同時也引入了更多複雜性。

如果沒有針對緩存進行比較好的處理,某些場景下甚至會導致整個系統崩潰。

這次我們要聊的就是:緩存穿透。

緩存穿透

緩存穿透是指在查詢緩存數據時,緩存中沒有對應數據,還需要去存儲系統中查詢數據。

一般有以下兩種情況:

對應數據根本不存在

如果存儲系統中沒有某個數據,一般不會在緩存中存儲相應的數據。

這樣就導致在查詢緩存數據的時候,在緩存中找不到對應的數據,每次都要去存儲系統中再查詢一遍,然後返回數據不存在。

在這個場景中,緩存並沒有起到分擔存儲系統訪問壓力的作用。

讀取不存在的數據的請求量一般不會太大,但如果出現一些惡意攻擊,故意大量訪問某些不存在的數據,就會對存儲系統造成很多壓力。

解決辦法

  1. 如果查詢存儲系統的數據沒有找到,則直接設置一個特定值存到緩存中。之後讀取緩存時就會獲取到這個特定值,直接返回空值,就不會繼續訪問存儲系統了。

  2. 把已存在數據的key存放在布隆過濾器中。當有新的請求時,先到布隆過濾器中查詢是否存在,如果不存在該條數據直接返回;如果存在該條數據再查詢緩存查詢存儲系統。

緩存數據時生成耗時較長

存儲系統中存在對應的數據,但生成緩存數據需要耗費較長時間或者大量資源。

如果剛好在訪問的時候對應的緩存失效了,那麼緩存不會發揮作用,訪問壓力全部都集中在存儲系統上。

比如某寶上的分類商品列表,因為數據量巨大,並且還有按銷量、信用、價格等各種排序,不可能把所有數據都緩存起來,所以只能按照分頁的頁數進行緩存。

如果每次點擊分頁的時候按分頁計算並生成緩存數據,一般情況下是沒問題的,因為真正的用戶不會從第一頁一直翻到最後一頁。

真正的用戶訪問一般都集中在前十頁,所以第十頁以後的緩存過期失效的可能性很大。

那麼問題就來了,假如被競爭對手用爬蟲來遍歷所有分頁的時候,此時很多分頁緩存可能都失效了,從存儲系統中生成緩存數據又非常耗費時間,所以爬蟲會將整個存儲系統全部拖慢,整個系統性能就可能出現問題。

解決辦法

  1. 限制分頁的數量,比如某寶上分類商品列表,最大分頁就到100頁。當然,從產品角度看,這樣的做法不是很好,因為100頁以後的商品將永遠不會被用戶看到。

  2. 後台作業定時更新緩存,而不是在訪問頁面時生成緩存數據。這樣可以按照一定策略定時更新緩存,不會對存儲系統較大的瞬時壓力。

總結

緩存穿透是指在查詢緩存數據時,緩存中沒有對應數據,還需要去存儲系統中查詢數據。

通常情況下有兩種情況:對應數據根本不存在、緩存數據時生成耗時較長。

微信公眾號:萬貓學社

微信掃描二維碼

關注後回復「電子書」

獲取12本Java必讀技術書籍

最後,感謝你的點贊關注,帥氣又美麗。