redis的雪崩、穿透和擊穿

前言

   最近看到redis的時候,發現有如下疑問:什麼是redis雪崩、穿透和擊穿?產生這些問題該怎麼辦?


緩存雪崩

是什麼

   如果你在使用redis的時候,遇到如下兩種情況,可能你就遇到緩存雪崩了。

情況一

  系統A,每天高峯併發量每秒5000個請求,緩存可以抗住4000請求,但是這時redis宕機了,此時每秒5000個請求的壓力都到了數據庫中,數據庫必然扛不住,然後就掛了。就算是DBA重啓數據庫,仍然會新的流量給打死,這就是緩存雪崩了

情況二

  系統B,每天高峯併發量每秒5000個請求,緩存可以抗住4000請求,這時所有的key值失效了,也就是過期時間到了,這時每秒5000個請求的壓力都到了數據庫中,數據庫必然扛不住,也會掛掉。這也是緩存雪崩。

在這裏插入圖片描述

該如何解決呢?

   如果你在使用redis的時候,遇到如下兩種情況,可能你就遇到緩存雪崩了。

緩存雪崩的事前、事中、事後的解決方案:

  • 事前:redis高可用,主從+哨兵,redis cluster,避免全盤崩潰。
  • 事中:本地ehcache緩存+Hystrix限流/降級,避免MySQL被打死。
  • 事後:redis持久化,一旦重啓,自動從磁盤上加載數據,快速恢復緩存數據。
  • 其他解決方法:java鎖實現限流、數據預熱、給緩存的失效時間,加上一個隨機值,避免集體失效、做二級緩存,或者雙緩存策略、緩存永不過期

參考資料:解決redis緩存穿透和緩存雪崩

在這裏插入圖片描述
  用戶發送一個請求,系統受到請求後,先查本地ehcache緩存,如果沒查到再查redis。如果ehcache和redis都沒有,再查數據庫,將數據庫中的結果,寫入ehcache和redis中。

  限流組件,可以設置每秒的請求,有多少能通過組件,剩餘的未通過的請求,怎麼辦?走降級!可以返回一些默認的值,或者友情提示,或者空白的值。

好處:

  • 數據庫絕對不會死,限流組件確保了每秒只有多少個請求能通過。
  • 只要數據庫不死,就是說,對用戶來說,2/5的請求都是可以被處理的。
  • 只要有2/5的請求可以被處理,就意味着你的系統沒死,對用戶來說,可能就是點擊幾次刷不出來頁面,但是多點幾次,就可以刷出來一次。

    


緩存穿透

是什麼

  對於系統A,假設每秒5000個請求,結果其中4000個請求是黑客發來的惡意攻擊。那4000個請求在緩存中查詢不到,然後進入到數據庫中也查詢不到。請求每次都“視緩存於無物”,直接查詢數據庫,也能直接把數據庫打死。

在這裏插入圖片描述

該如何解決呢?

  • 每次系統A從數據庫中查詢不到,就寫一個空值到緩存裏去,以請求參數爲key,null值爲value,設置過期時間,這樣下次有相同的key來訪問的時候,在緩存失效之前,都可以直接從緩存中取數據。
  • 設置布隆過濾:將所有可能存在的數據哈希到一個足夠大的bitmap中,一個一定不存在的數據會被這個bitmap攔截掉,從而避免了對底層數據庫的查詢壓力。

緩存擊穿

是什麼

  緩存擊穿,就說某個熱點key,訪問非常頻繁,處於集中式高併發訪問的情況,當這個key在失效的瞬間,大量的請求就擊穿了緩存,直接訪問數據庫,就像是在一道屏障上鑿開了一個洞。

該如何解決呢?

  • 將熱點數據設置爲永不過期
  • 基於redis 或者 zookeeper 實現互斥鎖,等待第一個請求構建完緩存之後,再釋放鎖,進而其他請求才能通過該key訪問數據。

黑色背景

小結

  有關redis的內容,在繼續深入的過程中,加深理解。明白爲什麼,該如何做。

感謝您的閱讀~~

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