緩存穿透
一般的緩存系統,都是按照key去緩存查詢,如果不存在對應的value,就去后端系統查找(比如DB)。
一些惡意的請求會故意查詢不存在的key,請求量很大,就會對后端系統造成很大的壓力。這就叫做緩存穿透。
?
如何避免?
1:對查詢結果為空的情況也進行緩存,這樣,再次訪問時,緩存層會直接返回空值。緩存時間設置短一點,或者該key對應的數據insert了之后清理緩存。
2:對一定不存在的key進行過濾。具體請看布隆過濾器
緩存擊穿
是針對緩存中沒有但數據庫有的數據。
場景是,當Key失效后,假如瞬間突然涌入大量的請求,來請求同一個Key,這些請求不會命中Redis,都會請求到DB,導致數據庫壓力過大,甚至扛不住,掛掉。
解決辦法
1、設置熱點Key,自動檢測熱點Key,將熱點Key的過期時間加大或者設置為永不過期,或者設置為邏輯上永不過期
2、加互斥鎖。當發現沒有命中Redis,去查數據庫的時候,在執行更新緩存的操作上加鎖,當一個線程訪問時,其它線程等待,這個線程訪問過后,緩存中的數據會被重建,這樣其他線程就可以從緩存中取值。
緩存雪崩
是指大量Key同時失效,對這些Key的請求又會打到DB上,同樣會導致數據庫壓力過大甚至掛掉。
解決辦法
1)讓Key的失效時間分散開,可以在統一的失效時間上再加一個隨機值,或者使用更高級的算法分散失效時間。
2)構建多個redis實例,個別節點掛了還有別的可以用。
3)多級緩存:比如增加本地緩存,減小redis壓力。
4)對存儲層增加限流措施,當請求超出限制,提供降級服務(一般就是返回錯誤即可)
?