當存儲系統成為瓶頸時,比如高並發、讀多寫少等場景,我們首先會想到的就是利用緩存來提高整個系統的性能。
緩存雖然能夠大大提升整個系統的性能,但同時也引入了更多復雜性。
如果沒有針對緩存進行比較好的處理,某些場景下甚至會導致整個系統崩潰。
這次我們要聊的就是:緩存穿透。
緩存穿透
緩存穿透是指在查詢緩存數據時,緩存中沒有對應數據,還需要去存儲系統中查詢數據。
一般有以下兩種情況:
對應數據根本不存在
如果存儲系統中沒有某個數據,一般不會在緩存中存儲相應的數據。
這樣就導致在查詢緩存數據的時候,在緩存中找不到對應的數據,每次都要去存儲系統中再查詢一遍,然后返回數據不存在。
在這個場景中,緩存並沒有起到分擔存儲系統訪問壓力的作用。
讀取不存在的數據的請求量一般不會太大,但如果出現一些惡意攻擊,故意大量訪問某些不存在的數據,就會對存儲系統造成很多壓力。
解決辦法
-
如果查詢存儲系統的數據沒有找到,則直接設置一個特定值存到緩存中。之后讀取緩存時就會獲取到這個特定值,直接返回空值,就不會繼續訪問存儲系統了。
-
把已存在數據的key存放在布隆過濾器中。當有新的請求時,先到布隆過濾器中查詢是否存在,如果不存在該條數據直接返回;如果存在該條數據再查詢緩存查詢存儲系統。
緩存數據時生成耗時較長
存儲系統中存在對應的數據,但生成緩存數據需要耗費較長時間或者大量資源。
如果剛好在訪問的時候對應的緩存失效了,那么緩存不會發揮作用,訪問壓力全部都集中在存儲系統上。
比如某寶上的分類商品列表,因為數據量巨大,並且還有按銷量、信用、價格等各種排序,不可能把所有數據都緩存起來,所以只能按照分頁的頁數進行緩存。
如果每次點擊分頁的時候按分頁計算並生成緩存數據,一般情況下是沒問題的,因為真正的用戶不會從第一頁一直翻到最后一頁。
真正的用戶訪問一般都集中在前十頁,所以第十頁以后的緩存過期失效的可能性很大。
那么問題就來了,假如被競爭對手用爬蟲來遍歷所有分頁的時候,此時很多分頁緩存可能都失效了,從存儲系統中生成緩存數據又非常耗費時間,所以爬蟲會將整個存儲系統全部拖慢,整個系統性能就可能出現問題。
解決辦法
-
限制分頁的數量,比如某寶上分類商品列表,最大分頁就到100頁。當然,從產品角度看,這樣的做法不是很好,因為100頁以后的商品將永遠不會被用戶看到。
-
后台作業定時更新緩存,而不是在訪問頁面時生成緩存數據。這樣可以按照一定策略定時更新緩存,不會對存儲系統較大的瞬時壓力。
總結
緩存穿透是指在查詢緩存數據時,緩存中沒有對應數據,還需要去存儲系統中查詢數據。
通常情況下有兩種情況:對應數據根本不存在、緩存數據時生成耗時較長。
微信公眾號:萬貓學社
微信掃描二維碼
關注后回復「電子書」
獲取12本Java必讀技術書籍

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