三個常見的緩存異常就斤,分別是緩存雪崩悍募、緩存擊穿和緩存穿透蘑辑。
緩存雪崩
緩存雪崩造成的結果是:數據庫壓力大
原因有兩點:
原因一:緩存中有大量數據同時過期,且次數大量并發(fā)請求
方案:
發(fā)生雪崩前:避免給大量的數據設置相同的過期時間坠宴,過期時間增加一個較小的隨機數(例如洋魂,隨機增加 1~3 分鐘)
發(fā)生雪崩時:(減少請求數目,數據庫的壓力就沒有那么大了)
服務降級---------非核心業(yè)務數據(返回固定值:預定義信息喜鼓、空值或是錯誤信息)副砍;
核心業(yè)務數據 (仍然允許查詢緩存,如果緩存缺失庄岖,也可以繼續(xù)通過數據庫讀然眙帷) 。
原因二:Redis 實例發(fā)生了宕機
方案:
Redis還未宕機:構建 Redis 緩存高可靠集群隅忿;
Redis已經宕機:采用服務熔斷或請求限流機制心剥;
前置準備:監(jiān)測 Redis 緩存所在機器和數據庫所在機器的負載指標,例如每秒請求數背桐、CPU 利用率优烧、內存利用率等。
如果我們發(fā)現(xiàn) Redis 緩存實例宕機了链峭,而數據庫所在機器的負載壓力突然增加畦娄,此時,就發(fā)生緩存雪崩了弊仪。
緩存擊穿
熱點數據在緩存中失效熙卡,訪問該數據的大量請求,對后端數據庫找出極大壓力
方案:對于訪問特別頻繁的熱點數據励饵,不設置過期時間
緩存穿透
要訪問的數據既不在 Redis 緩存中驳癌,也不在數據庫中。緩存如同擺設曲横,也出現(xiàn)了出現(xiàn)了不必要的IO和數據庫請求喂柒。
原因有兩點:
原因一:業(yè)務層誤操作不瓶。(緩存中的數據和數據庫中的數據被誤刪除了,所以緩存和數據庫中都沒有數據)
原因二:惡意攻擊灾杰。
方案:
1蚊丐,緩存空值或缺省值。
2艳吠,使用布隆過濾器快速判斷數據是否存在
3麦备,請求入口檢測(常用,一個token碼識別是否程序支持用戶昭娩。惡意請求時直接把該用戶拉入黑名單)
補充
布隆過濾器可以放在緩存和數據庫的最前面:把Redis當作布隆過濾器時凛篙,當用戶產生業(yè)務數據寫入緩存和數據庫后,同時也寫入布隆過濾器栏渺,之后當用戶訪問自己的業(yè)務數據時呛梆,先檢查布隆過濾器,如果過濾器不存在磕诊,就不需要查詢緩存和數據庫了填物,可以同時降低緩存和數據庫的壓力。
Redis布隆過濾器是使用String類型實現(xiàn)的霎终,存儲的方式是一個bigkey滞磺,建議使用時單獨部署一個實例,專門存放布隆過濾器的數據莱褒,不要和業(yè)務數據混用击困,否則在集群環(huán)境下,數據遷移時會導致Redis阻塞問題广凸。