目錄
一、緩存穿透
緩存穿透的原因:
緩存穿透的現象:
緩存穿透的解決辦法:
二、緩存擊穿
緩存擊穿的原因:
緩存擊穿的現象:
緩存擊穿的解決辦法:
三、緩存雪崩
緩存雪崩的原因:
緩存雪崩的現象:
緩存雪崩的解決辦法:
一、緩存穿透
情景再現:
當用戶請求服務器查找數據,通常操作比較頻繁的數據我們會在Redis里面去查詢,如果Redis沒有,按理來說我們應該去數據庫查,查完之后再同步到Redis中去。如果在數據庫里也查不到就無法同步到緩存中去,造成緩存穿透
示意圖:?
緩存穿透的原因:
1.key對應數據的數據源不存在,每次針對此key的請求從緩存中都獲取不到,都會壓到數據源,就可能壓垮數據源
2.比如:我們用一個不存在的用戶id查詢信息,數據庫和緩存都沒有,黑客就可以利用此漏洞進行攻擊
3.也就是說,如果從存儲層查不到數據則不會寫入緩存,這將導致這個不存在的數據每次都要去存儲層查詢,失去了緩存的意義?,頻繁查詢就會壓垮數據庫
緩存穿透的現象:
1.應用服務器壓力變大
2.Redis命中率低
3.一直查數據庫
緩存穿透的解決辦法:
1.對空值緩存
如果一個查詢返回的數據是空,我們仍然把這個空結果(null)進行緩存,設置空結果的時間應該短一些(小于5min),因為也可能是臨時沒有的
2.設置可訪問的白名單
定義一個可訪問的白名單,每次訪問的名單和白名單id進行比較,如果訪問id不在白名單里面就進行攔截不允許訪問,可以通過bitmaps實現
3.采用布隆過濾器
布隆過濾器可以檢索一個元素是否在集合中。他的優點就是空間效率和時間效率都遠遠高要求其他算法,缺點是有一定的誤識別率和刪除困難
4.進行實時監控
當發現Redis命中率急速降低的時候,需要排查訪問對象和數據,和運維人員配合,設置黑名單限制服務
二、緩存擊穿
情景再現:
當用戶請求服務器查找數據,但是key過期了就會越過Redis去訪問數據庫,導致數據庫瞬間訪問量過大
示意圖:
緩存擊穿的原因:
?1、key對應的數據存在,但在Redis中過期,此時如果大量的并發請求過來,就會發現緩存過期,于是從DB加載數據并且回到Redis,這個大量的并發請求就可能把DB壓垮
2、比如某一個熱點數據,在某個時間點瞬間被超高并發的訪問就會壓垮數據庫,出現緩存擊穿
緩存擊穿的現象:
?1、數據庫訪問壓力瞬間增加
2、Redis里面沒有出現大量key過期
3、Redis正常運行,數據庫癱瘓了
緩存擊穿的解決辦法:
1、預先設置熱門數據
在redis高峰訪問之前、把這些熱門數據加到redis里面去,加大熱門數據的key時長
2、實時調整
現場監控哪些熱門數據,加大key時長
3、使用鎖
給數據庫設置一個排它鎖,當用戶從redis中查不到key對應的數據(返回為null),就去數據庫查,此時會上鎖,只有單線程通過,拿到數據之后同步到redis中,此時如果其他線程來訪問就會休眠一段時間然后重新訪問redis。最終拿到數據
1)就是在緩存失效的時候(判斷拿出來的值為空),不是立即去load db。
2)先使用緩存工具的某些帶成功操作(比如Redis的SETNX)去set一個mutex key
3)當操作返回成功時,再進行load db的操作,并回設緩存,最后刪除mutex key;
4)當操作返回失敗,證明有線程在load db,當前線程睡眠一段時間再重試整個get緩存的方法
5)使用鎖,效率會有影響?
三、緩存雪崩
情景再現:
當用戶發送web請求到Nginx,Nginx轉發大量請求到對應的服務器,然后大量的請求訪問緩存,如果緩存數據大量過期,就會去數據庫更新。如果此時出現緩存雪崩,那么從數據庫更新數據就會失敗
示意圖:
緩存雪崩的原因:
1、大量的并發請求去請求不同的key,key對應的數據在redis中大量過期,然后通常會從DB加載數據并回設到緩存,但此時大并發請求就會把DB壓垮。
2、緩存擊穿針對一個key,緩存雪崩針對很多key
緩存雪崩的現象:
?1、數據庫訪問壓力過大,服務器崩潰
2、在極短的時間內,訪問大量的key,而這些key集中過期
緩存雪崩的解決辦法:
1、構建多級緩存架構
nginx架構+redis緩存+其他緩存(ehcache等),這種方式開發/維護成本高
2、使用鎖或者隊列
用加鎖或者隊列的方式來保證不會有大量的線程對數據庫一次性進行讀寫,從而避免失效時大量的并發請求到底層存儲系統上
3、設置過期時間更新緩存
記錄緩存數據是否過期,如果過期會觸發通知另外的線程在后臺去更新實際key的緩存,讓key不要集中過期,保證key一直在redis。?
4、將緩存失效時間分散開
可以在原有的失效時間上加一個隨機值(1min~5min),分散開就可以