什么是緩存穿透?
發生場景
緩存穿透的概念很簡單,用戶想要查詢一個數據,發現redis內存數據庫沒有,也就是緩存沒有命中,於是向持久層數據庫查詢。
發現也沒有,於是本次查詢失敗。當用戶很多的時候,緩存都沒有命中,於是都去請求了持久層數據庫。
這會給持久層數據庫造成很大的壓力,這時候就相當於出現了緩存穿透。
解決方案
1、對請求參數做校驗,例如可以用正則;
2、緩存空對象, 當存儲層不命中后,即使返回的空對象也將其緩存起來,同時會設置一個過期時間,之后再訪問這個數據將會從緩存中獲取,保護了后端數據源;
但是這種方法會存在兩個問題:
2.1、 如果空值能夠被緩存起來,這就意味着緩存需要更多的空間存儲更多的鍵,因為這當中可能會有很多的空值的鍵;
2.2、即使對空值設置了過期時間,還是會存在緩存層和存儲層的數據會有一段時間窗口的不一致,這對於需要保持一致性的業務會有影響。
3、可以引入布隆過濾器,過濾一些異常的請求。https://blog.csdn.net/wuzhiwei549/article/details/106714765
什么是緩存擊穿?
發生場景
緩存擊穿,是指一個key非常熱點,在不停的扛着大並發,大並發集中對這一個點進行訪問,
當這個key在失效的瞬間,持續的大並發就穿破緩存,直接請求數據庫,就像在一個屏障上鑿開了一個洞。
解決方案
1、可以將熱點數據的過期時間設置為永久有效(有人可能會問,萬一這個熱點商品下架了,這個緩存不就成了了臟數據嗎?其實會有這種場景存在,主要還是具體情況具體分析,看業務場景吧);
2、維護一個定時任務,將快要過期的key重新設置;
3、可以使用分布式鎖,當在緩存中拿不到數據時,使用分布式鎖去數據庫中拿到數據后,重新設置到緩存;