Redis常見緩存問題

1. 什麼是緩存穿透?

緩存一般都是key,value的形式,通過key先去緩存中查,沒有再去數據庫查。如果故意訪問一些本來就不存在就key,就會導致一直去查數據庫,如果併發量很大的話,會對數據庫造成很大壓力。簡單來說就是通過不存在的key穿過緩存,請求到數據庫
解決方案
1.通過key從數據庫沒查詢到數據也進行緩存,將緩存失效時間設置短一點。
2.對key進行過濾,過濾掉不符合的key(比如布隆表達式)。

2. 什麼是緩存雪崩?

當緩存服務器重啓或者大量緩存集中在某一個時間段失效,在這段時間大量請求到數據庫。
解決方案:
1:在緩存失效後,通過加鎖或者隊列來控制讀數據庫寫緩存的線程數量,減少數據庫壓力。(通過key從緩存中沒有查詢數據時,再查詢數據庫,對查查詢數據庫的操作加鎖)。

2:不同的key設置不同的過期時間,防止同時大量key過期。

3. 緩存擊穿

當前有大量請求訪問,剛好某個key過期了,就會同時有許多請求去查詢數據庫,給數據庫造成壓力(緩存雪崩是大量key失效)。
解決方案:查詢數據庫的操作加互斥鎖,或者由消息隊列來同步數據庫信息到緩存中。

4. 緩存一致性

查詢步驟

先查詢緩存,緩存中沒有再查詢數據庫,然後將查詢結果放到緩存中。

更新步驟

1.先更新數據庫再更新緩存(不建議使用)

  • 操作步驟(線程A和線程B都對同一數據進行更新操作):
  1. 線程A更新了數據庫
  2. 線程B更新了數據庫
  3. 線程B更新了緩存
  4. 線程A更新了緩存```
  • 問題1:髒讀(正確情況下,緩存中應該放入的是線程b的數據)

  • 問題2:浪費性能

2.先更新數據庫再刪除緩存

操作步驟(線程A更新、線程B讀)

  • 請求A進行寫操作,刪除緩存,此時A的寫操作還沒有執行完
  • 請求B查詢發現緩存不存在
  • 請求B去數據庫查詢得到舊值
  • 請求B將舊值寫入緩存
  • 請求A將新值寫入數據庫

解決方案
1:延時雙刪策略(先刪除緩存,然後sleep一會,再刪除緩存,影響接口響應速度)
2:使用消息隊列

還有一下其他情況,大家可以自行查資料;沒有百分百完美的方案,主要是看業務需求,根據具體請求找合適的解決方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章