緩存雪崩、緩存穿透、緩存擊穿

一、緩存雪崩

    當緩存大規模滲透在整個架構中以後,那麼緩存本身的可用性將決定整個架構的穩定性。

    緩存雪崩是指設置緩存時採用了相同的過期時間,導致緩存在某一個時刻同時失效,或者緩存服務器宕機宕機,導致緩存全面失效,請求全部轉發到了DB層面,DB由於瞬間壓力增大而導致崩潰。 緩存失效導致的雪崩效應對底層系統的衝擊是很大的。

解決方式:

    1.  對緩存的訪問,如果發現從緩存中取不到值,那麼通過加鎖或者隊列的方式保證緩存的單進程操作,從而避免失效時併發請求全部落到底層的存儲系統上;但是這種方式會帶來性能上的損耗

    2. 將緩存失效的時間分散,降低每一個緩存過期時間的重複率

    3.  如果是因爲緩存服務器故障導致的問題,一方面需要保證緩存服務器的高可用、另一方面,應用程序中可以採用多級緩存

舉例:

    比如馬上就要到雙十二零點,很快就會迎來一波搶購,這波商品時間比較集中的放入了緩存,假設緩存一個小時。那麼到了凌晨一點鐘的時候,這批商品的緩存就都過期了。而對這批商品的訪問查詢,都落到了數據庫上,對於數據庫而言,就會產生週期性的壓力波峯。

    做電商項目的時候,一般是採取不同分類商品,緩存不同週期。在同一分類中的商品,加上一個隨機因子。這樣能儘可能分散緩存過期時間,而且,熱門類目的商品緩存時間長一些,冷門類目的商品緩存時間短一些,也能節省緩存服務的資源。

 

    緩存時間加入隨機因子:其實集中過期,倒不是非常致命,比較致命的緩存雪崩,是緩存服務器某個節點宕機或斷網。 因爲自然形成的緩存雪崩,一定是在某個時間段集中創建緩存,那麼那個時候數據庫能頂住壓力,這個時候,數據庫也是可以頂住壓力的。無非就是對數據庫產生週期性的壓力而已。而緩存服務節點的宕機,對數據庫服務器造成的壓力是不可預知的,很有可能瞬間就把數據庫壓垮。

 

 

二、緩存穿透

     緩存穿透是指查詢一個根本不存在的數據,緩存和數據源都不會命中。出於容錯的考慮,如果從數據層查不到數據   則不寫入緩存,即數據源返回值爲 null 時,不緩存  null。緩存穿透問題可能會使後端數據源負載加大,由於很多後端數據源不具備高併發性,甚至可能造成後端數據源宕掉

    就是很大一部分的請求,在緩存都拿不到數據,最終都落到數據庫上,此時數據庫的IO和訪問量會特別大,會導致數據庫宕機。 或者也可以說,當查詢一些根本都不會存在的數據,會導致緩存和數據源都不會命中,這就叫緩存穿透擊穿。

    一般的惡意請求,會導致緩存擊穿

解決方法1:

    訪問key未在DB查詢到值,也將空值寫進緩存,但可以設置較短過期時間。

解決方法2:設置默認值

     如果查詢數據庫也爲空,直接設置一個默認值存放到緩存,這樣第二次到緩衝中獲取就有值了,而不會繼續訪問數據庫,這種辦法最簡單粗暴。比如,”key” , “&&”。

    默認值: 當查詢數據爲空,設置一個默認值,這個默認值有一個規律(key —> &&),定時輪詢查key,是否又有數據了

    在返回這個&&值的時候,我們的應用就可以認爲這是不存在的key,那我們的應用就可以決定是否繼續等待繼續訪  問,還是放棄掉這次操作。如果繼續等待訪問,過一個時間輪詢點後,再次請求這個key,如果取到的值不再是 &&,則可以認爲這時候key有值了,從而避免了透傳到數據庫,從而把大量的類似請求擋在了緩存之中。

解決方法3:布隆過濾器

    本人另一篇博文: https://blog.csdn.net/kzadmxz/article/details/100641375

    根據緩存數據Key的設計規則,將不符合規則的key進行過濾

    採用布隆過濾器,將所有可能存在的數據哈希到一個足夠大的BitSet中,不存在的數據將會被攔截掉,從而避免了   對底層存儲系統的查詢壓力

 

 

三、緩存擊穿

    緩存擊穿,是指一個key非常熱點,在不停的扛着大併發,大併發集中對這一個點進行訪問,當這個key在失效的瞬間持續的大併發就穿破緩存,直接請求數據庫,就像在一個屏障上鑿開了一個洞。

    其實,在做電商項目的時候,大多數情況下爆款也很難對數據庫服務器造成壓垮性的壓力。達到這個級別的公司沒有幾家的。所以,處理方法是,對主打商品都是早早的做好了準備,讓緩存永不過期。 即便某些商品自己發酵成了爆款,也是直接設爲永不過期就好了。

 

 

 

 

 

 

 

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