瞭解什麼是 redis 的雪崩、穿透和擊穿?redis 崩潰以後會怎麼樣?系統該如何應對這種狀況?如何處理 redis 的穿透?java
其實這是問到緩存必問的,由於緩存雪崩和穿透,是緩存最大的兩個問題,要麼不出現,一旦出現就是致命性的問題,因此面試官必定會問你。git
對於系統 A,假設天天高峯期每秒 5000 個請求,原本緩存在高峯期能夠扛住每秒 4000 個請求,可是緩存機器意外發生了全盤宕機。緩存掛了,此時 1 秒 5000 個請求所有落數據庫,數據庫必然扛不住,它會報一下警,而後就掛了。此時,若是沒有采用什麼特別的方案來處理這個故障,DBA 很着急,重啓數據庫,可是數據庫立馬又被新的流量給打死了。github
這就是緩存雪崩。面試
大約在 3 年前,國內比較知名的一個互聯網公司,曾由於緩存事故,致使雪崩,後臺系統所有崩潰,事故從當天下午持續到晚上凌晨 3~4 點,公司損失了幾千萬。redis
緩存雪崩的事前事中過後的解決方案以下。數據庫
用戶發送一個請求,系統 A 收到請求後,先查本地 ehcache 緩存,若是沒查到再查 redis。若是 ehcache 和 redis 都沒有,再查數據庫,將數據庫中的結果,寫入 ehcache 和 redis 中。緩存
限流組件,能夠設置每秒的請求,有多少能經過組件,剩餘的未經過的請求,怎麼辦?走降級!能夠返回一些默認的值,或者友情提示,或者空白的值。併發
好處:分佈式
對於系統A,假設一秒 5000 個請求,結果其中 4000 個請求是黑客發出的惡意攻擊。高併發
黑客發出的那 4000 個攻擊,緩存中查不到,每次你去數據庫裏查,也查不到。
舉個栗子。數據庫 id 是從 1 開始的,結果黑客發過來的請求 id 所有都是負數。這樣的話,緩存中不會有,請求每次都「視緩存於無物」,直接查詢數據庫。這種惡意攻擊場景的緩存穿透就會直接把數據庫給打死。
解決方式很簡單,每次系統 A 從數據庫中只要沒查到,就寫一個空值到緩存裏去,好比 set -999 UNKNOWN
。而後設置一個過時時間,這樣的話,下次有相同的 key 來訪問的時候,在緩存失效以前,均可以直接從緩存中取數據。
緩存擊穿,就是說某個 key 很是熱點,訪問很是頻繁,處於集中式高併發訪問的狀況,當這個 key 在失效的瞬間,大量的請求就擊穿了緩存,直接請求數據庫,就像是在一道屏障上鑿開了一個洞。
解決方式也很簡單,能夠將熱點數據設置爲永遠不過時;或者基於 redis or zookeeper 實現互斥鎖,等待第一個請求構建完緩存以後,再釋放鎖,進而其它請求才能經過該 key 訪問數據。
免費Java資料須要本身領取,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高併發分佈式等教程,一共30G。
傳送門:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q