這篇文章,我們將介紹什么是緩存穿透、緩存擊穿與緩存雪崩,以及對應的解決方案。
1.緩存穿透
緩存穿透,是指查詢一個不存在的數據,由於數據不存在,所以數據不會被緩存,每次查詢都是從數據庫中去查詢。如果有人利用這個存在的漏洞去偽造大量的請求,那么很可能導致DB承受不了那么大的流量就掛掉了。
解決方案:
- 事前預防:對所有請求進行參數校驗(頁面或者接口中),拒絕非法請求
- 事后預防:當查詢到一個空的結果時,我們仍然將這個空的結果進行緩存,但是設置一個很短的過期時間。
2.緩存擊穿
緩存擊穿,就是在熱點key失效的瞬間,海量的請求訪問數據庫,導致數據庫崩潰。
解決方案:
- 互斥鎖:是在緩存KEY過期去更新的時候,先讓程序去獲取鎖,只有獲取到鎖的線程才有資格去更新緩存KEY。其他沒有獲取到鎖的線程則休眠片刻之后再次去獲取最新的緩存數據。通過這種方式,同一時刻永遠只有一個線程會去讀取數據庫,這樣也就避免了海量數據庫請求對於數據庫的沖擊。
- 永不過期:將緩存設置為永不過期,通過定時任務去同步緩存和數據庫的數據。
3.緩存雪崩
緩存雪崩,是指我們設置緩存時采用了相同的過期時間,導致很多key在某一時刻同時失效,請求全部轉發到數據庫,最終導致數據庫瞬時壓力過大而崩潰。
解決方案:
- 在原有失效時間的基礎上增加一個隨機時間(例如1-5分鍾),這樣每個緩存過期時間的重復率就會降低,從而減少緩存雪崩的發生。
總結:緩存穿透是業務層面的漏洞導致非法請求,與請求量、緩存失效沒關系。緩存擊穿則只會出現在熱點數據上,發生在緩存失效的瞬間,與業務沒多大關系。緩存雪崩則是因為多個 KEY 同時失效,導致數據庫請求太多。非熱點數據也會導致緩存雪崩,只要同時失效的 KEY 足夠多。