緩存穿透
緩存穿透是指查詢一個根本不存在的數(shù)據(jù),緩存層和存儲層都不會命中,通常處于容錯考慮,如果從存儲層查不到數(shù)據(jù),則不寫入緩存層。
緩存穿透將導致不存在的數(shù)據(jù)每次請求都要到存儲層去查詢,失去了緩存保護后端存儲的意義。
造成緩存穿透的基本原因有兩個:
- 自身業(yè)務代碼或者數(shù)據(jù)出現(xiàn)問題。
- 惡意攻擊、爬蟲等造成大量空命中。
緩存穿透問題的解決方案:
- 緩存空對象
- 布隆過濾器
緩存擊穿(失效)
由于大批量緩存在同一時間失效可能導致大量請求同時穿透緩存直達數(shù)據(jù)庫,可能會造成數(shù)據(jù)庫瞬間壓力過大甚至掛掉,對于這種情況我們在批量增加緩存時最好將這一批數(shù)據(jù)的緩存時間設置為一個時間段內(nèi)的不同時間(固定時間+隨機時間)。
緩存雪崩
緩存雪崩指的是緩存層支撐不住或宕機后,大量流量會直接訪問后端存儲層。
由于緩存層承載著大量請求,有效的保護了存儲層,但是如果緩存層由于某些原因不能提供服務(例如:超大并發(fā),緩存層無法承受;緩存設計不好,出現(xiàn)大量Bigkey訪問,導致緩存能支持的并發(fā)急劇下降。),于是大量請求會直接訪問后端存儲層,后端存儲層的調用量會暴增,造成后端存儲層也會跟著宕機的情況。
預防和解決緩存雪崩問題,可以從以下三個方面著手。
- 保證緩存層服務高可用性。例如redis sentinel或者Redis Cluster
- 依賴隔離組件為后端限流熔斷并降級。比如使用sentinel或者Hystrix限流降級組件。
- 提前演練。在項目上線前,演練緩存層宕機后,應用以及后端負載情況以及可能出現(xiàn)的問題,在此基礎上做預案設計。
熱點緩存key重建優(yōu)化
開發(fā)人員使用”緩存+過期時間“的策略來實現(xiàn)加速數(shù)據(jù)讀寫與數(shù)據(jù)能定期更新,這種模式基本能夠滿足絕大部分需求。但是有兩個問題如果同時出現(xiàn),可能就會對應用造成致命的危害:
- 當前key是一個熱點key(出軌微博),并發(fā)量非常大。
- 重建緩存不能在短時間完成,可能是一個復雜計算,例如復雜SQL,多次IO、多個依賴等。
在緩存失效瞬間,有大量線程來重建緩存,造成后端負載加大,甚至可能會讓應用崩潰。
要解決這個問題主要是避免大量線程同時重建緩存。通過互斥鎖來保證同時只有一個線程再重建緩存,其他線程等待片刻后重新獲取緩存。