緩存問題及解決方案

1、緩存穿透

緩存穿透是指查詢一個一定不存在的數據,由於緩存中沒有這個數據,所以會去查詢數據庫,但是數據庫也沒有這條數據,並且處於容錯考慮,我們沒有將這次查詢的null寫入緩存,這將導致每次請求這條數據都需要查詢數據庫,失去了緩存的意義。在流量大時,可能DB就掛掉了,要是有人利用不存在的key頻繁攻擊我們的應用,這就是漏洞。

解決:
將空結果(null)放進緩存,但它的過期時間會很短,最長不超過五分鐘。

2、緩存雪崩

緩存雪崩是緩存中的數據在同一時間過期(即我們設置了相同的過期時間),導致緩存在某一時刻同時失效,恰好此時這條數據被超級多的請求訪問,那麼這些請求全部轉發到DB,DB瞬時壓力過重雪崩。

解決:
原有的失效時間基礎上增加一個隨機值,比如1-5分鐘隨機,這樣每一個緩存的過期時間的重複率就會降低,就很難引發集體失效的事件。

3、緩存擊穿

假設在我們的緩存中存放着一條非常"熱點"的數據,它被多個線程超級頻繁的訪問。但是在那麼一個時間點,它過期了,那麼會發生什麼了?大量的請求打進了數據庫,瞬間造成數據庫壓力過大,極有可能數據庫就這樣宕掉了。這種單個熱點的數據失效,我們把它稱爲緩存擊穿;而如果是大面積的數據失效,我們則稱它爲緩存雪崩。

解決:
分佈式鎖(這是個什麼玩意?)

4、分佈式鎖

上面記錄到:一條熱點數據在被多個線程高頻訪問的時候失效了,我們直觀的解決方法就是再把它拿到緩存中不就行了嘛。可是,如果這樣這樣做的話,我們需要考慮一個問題:背景是多個線程並行訪問,難不成讓它們都去數據庫取數據,然後放入緩存中?稍加思索就會明白,這樣做肯定是不可取得,不說重複冗餘,DB它也承受不住啊~ 那。。。。派個代表去數據庫取數據,再放入緩存中?這麼一想就靠譜多了,於是引出分佈式鎖的概念:保證有且只有這麼一個線程代表可以去數據庫取數據,並將其放入緩存中!

舉個不太恰當的栗子:假設我們的系統有緩存服務器和數據庫服務器,我們對數據庫服務器上了鎖,並且配有一把鑰匙。有那麼一個時間點,大量的線程發起請求去緩存服務器中訪問同一個數據,結果發現它過期了(不存在了)。然後就需要那麼 一個線程代表去數據庫中取數據,放進緩存中供大家訪問 ~ 於是乎,這個線程代表拿到了數據庫的鑰匙,可以打開數據庫服務器的大門取數據,其他的線程們就只能在數據庫外邊轉圈等它完成任務(這一過程稱爲自旋),最後大家都去訪問緩存服務器了。這個小栗子大概就說明了分佈式鎖的用途和原理—— 控制分佈式系統有序的去對共享資源進行操作,通過互斥來保持一致性。

悄咪咪留個坑——redisson,以後有機會再學習。。ok,就醬~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章