快取穿透、快取擊穿、快取雪崩、快取預熱

初夏†失忆發表於2024-06-07

快取穿透

快取穿透是指查詢一個根本不存在的資料,快取層和儲存層都不會命中,快取穿透將導致不存在的資料每次請求都要到儲存層去查詢,失去了快取保護後端儲存的意義(查詢一個根本不存在的key)
例子:查詢一個redis中沒有,資料庫中也沒有的資料,如果高頻率的查詢,就有可能導致資料庫崩潰
出現的基本原因:
  1. 自身業務程式碼或者資料出現問題
  2. 一些惡意攻擊、爬蟲等造成大量空命中
解決方案
  1. 當查詢結果為空的話,也把資料加入快取,也就是加一個空快取.
  2. 介面層增加校驗:如使用者校驗、id做基礎校驗、id<=0的直接攔截
  3. 採用布隆過濾器:將所有可能存在的資料雜湊到一個足夠大的bitmap中,一個一定不存在的資料會被這個bitmap攔截掉,從而避免了對底層儲存系統的查詢壓力

快取擊穿

高併發下,由於一個key失效,而導致多個執行緒去mysql查詢同一個業務資料並存到redis(併發下存了多份資料),而一段時間後,多份資料同時失效,導致壓力劇增
解決方案
  1. 分級快取:快取兩份資料,第二份資料生存時間長一點作為備份,第一份資料用於請求命中,如果第二份資料被命中說明第一份資料已經過期,要去mysql請求資料衝重新快取兩份資料
  2. 計劃任務:假如資料生存時間為30分鐘,計劃任務就20分鐘執行一次更新快取資料

快取雪崩

redis服務由於負載過大而導致當機,導致mysql的負載過大也當機,最終整個系統癱瘓
例子:大量的key在同一時間失效,導致資料庫伺服器負載過大
解決方案
  1. 配置redis叢集
  2. 快取預熱
  3. 資料不要設定相同的過期時間,不然過期時間

快取預熱

快取預熱就是系統上線後,將相關快取的資料直接載入到快取系統。這樣就可以避免在使用者請求的時候,先查詢資料庫,然後再將資料快取的問題。使用者可直接查詢事先被預熱的資料。
解決方案
  1. 直接寫一個快取重新整理頁面,上線時手工操作一下
  2. 資料量不大,可以在專案啟動的時候自動進行載入
  3. 定時重新整理快取

相關文章