緩存雪崩
對于系統 A,假設每天高峰期每秒 5000 個請求,本來緩存在高峰期可以扛住每秒 4000 個請求,但是緩存機器意外發生了全盤當機。緩存挂了,此時 1 秒 5000 個請求全部落資料庫,資料庫必然扛不住,它會報一下警,然後就挂了。此時,如果沒用什麼特别的方案來處理這個故障,DBA 很着急,重新開機資料庫,但是資料庫立馬又被新的流量給打死了。
這就是緩存雪崩。

大約在 3 年前,國内比較知名的一個網際網路公司,曾因為緩存事故,導緻雪崩,背景系統全部崩潰,事故從當天下午持續到晚上淩晨 3~4 點,公司損失了幾千萬。
緩存雪崩的事前事中事後的解決方案如下。
- 事前:redis 高可用,主從+哨兵,redis cluster,避免全盤崩潰。
- 事中:本地 ehcache 緩存 + hystrix 限流&降級,避免 MySQL 被打死。
- 事後:redis 持久化,一旦重新開機,自動從磁盤上加載資料,快速恢複緩存資料。
使用者發送一個請求,系統 A 收到請求後,先查本地 ehcache 緩存,如果沒查到再查 redis。如果 ehcache 和 redis 都沒有,再查資料庫,将資料庫中的結果,寫入 ehcache 和 redis 中。
限流元件,可以設定每秒的請求,有多少能通過元件,剩餘的未通過的請求,怎麼辦?走降級!可以傳回一些預設的值,或者友情提示,或者空白的值。
好處:
- 資料庫絕對不會死,限流元件確定了每秒隻有多少個請求能通過。
- 隻要資料庫不死,就是說,對使用者來說,2/5 的請求都是可以被處理的。
- 隻要有 2/5 的請求可以被處理,就意味着你的系統沒死,對使用者來說,可能就是點選幾次刷不出來頁面,但是多點幾次,就可以刷出來一次。
緩存穿透
對于系統A,假設一秒 5000 個請求,結果其中 4000 個請求是黑客發出的惡意攻擊。
黑客發出的那 4000 個攻擊,緩存中查不到,每次你去資料庫裡查,也查不到。
舉個栗子。資料庫 id 是從 1 開始的,結果黑客發過來的請求 id 全部都是負數。這樣的話,緩存中不會有,請求每次都“視緩存于無物”,直接查詢資料庫。這種惡意攻擊場景的緩存穿透就會直接把資料庫給打死。
解決方式很簡單,每次系統 A 從資料庫中隻要沒查到,就寫一個空值到緩存裡去,比如
set -999 UNKNOWN
。這樣的話,下次便能走緩存了。