Redis 快取穿透、快取雪崩原理及解決方案

迷途碼界發表於2018-09-06

Redis快取的場景

客戶端請求在快取層命中就直接返回,如果miss就去讀取儲存層,儲存層讀取到就寫入快取層,然後再返回到客戶端


這裡寫圖片描述

Redis的優缺點

  • 優點:加速讀寫,降低後端負載、減少DB壓力
  • 缺點:資料不能保證一致性,程式碼維護成本和運維成本

快取穿透

引發原因

在查詢一個一定不存在的資料,由於快取是不命中時被動寫入,並且處於容錯考慮,如果從儲存層查不到資料則不寫入快取,這將導致這個不存在的資料每次請求都要到儲存層去查詢,快取層失去意義。
當在大流量流入時,可能因為頻繁訪問儲存層導致DB直接當機,這樣會形成被人利用不存在的key頻繁攻擊應用的漏洞。


快取穿透原因

解決方法

有多種方法能有效解決快取穿透的問題

  1. 最為常簡的是採用布隆過濾器,將所有可能存在的資料雜湊到一個足夠發的 bigmap 中,一個一定不存在的資料會被該 bigmap 攔截掉,從而避免對底層儲存系統造成查詢壓力。
  2. 另一種更為簡單的方法,如果一個查詢返回的資料為空(無論資料為空,或是系統故障),將空結果進行快取,設定一個最長不超過五分鐘的過期時間。

    這裡寫圖片描述

快取雪崩

引發原因
  1. 設定快取時採用了相同的過期時間,導致快取在某時刻同時失效,請求全部轉向DB,DB瞬時壓力過重雪崩。
  2. Redis當機,導致客戶端的請求之間流向DB,拖垮DB。

    這裡寫圖片描述
解決方發

有多種方法能有效解決快取雪崩的問題

問題一的解決方案

  1. 在快取失效後,通過加鎖或者佇列來控制讀資料庫寫快取的執行緒數量。比如對某個key只允許一個執行緒查詢資料和寫快取,其他執行緒等待。
  2. 簡單方案就是將快取失效時間分散開,我們可以在原有的失效時間基礎上增加一個隨機值,比如1-5分鐘隨機,這樣每一個快取的過期時間的重複率就會降低,就很難引發集體失效的事件。

問題二的解決方案

  1. 保持快取層伺服器的高可用。
    –監控、叢集、哨兵。當一個叢集裡面有一臺伺服器有問題,讓哨兵踢出去。
  2. 依賴隔離元件為後端限流並降級。
    比如推薦服務中,如果個性化推薦服務不可用,可以降級為熱點資料。
  3. 提前演練。
    演練 快取層crash後,應用以及後端的負載情況以及可能出現的問題。 對此做一些預案設定。

相關文章