一 、緩存穿透
一個數據在緩存中查不到,每次發起請求就會反覆去DB裏查,失去了緩存的意義。
如果這個不存在的數據被黑客發現,對應用發起攻擊,這就是漏洞。
緩存穿透解決方案
1 布隆過濾器
原理
布隆過濾器(Bloom Filter)的核心實現是一個超大的位數組和幾個哈希函數。假設位數組的長度爲m,哈希函數的個數爲3,假設集合裏面有3個元素{x, y, z}。首先將位數組每個位都初始化爲0。對於集合裏面的每一個元素,將元素依次通過3個哈希函數進行映射,每次映射都會產生一個哈希值,這個值對應位數組的一個點,將這裏標記爲1。查詢W元素是否存在集合中的時候,同樣的方法將W通過3個哈希函數進行映射,映射結果對應位數組的3個點。如果位數組中這3個點中有一個不爲1,則可以判斷該元素一定不存在集合中。反之,如果3個點都爲1,則該元素可能存在集合中。
缺點
隨着存入的元素數量增加,誤算率隨之增加,誤判率取決於hash算法;一般情況下不能從布隆過濾器中刪除元素。
2 空數據也寫入緩存
簡單粗暴的方法,如果去DB裏查詢到一個不存在的數據,同樣把空數據寫入緩存中,但是設置較短的過期時間,最長不超過5分鐘。
二、緩存雪崩
指緩存採用了相同的過期時間,它們在同一時刻失效,請求全部去DB進行查詢,DB壓力過大崩潰。
緩存雪崩解決方案
1 分散過期時間
最簡單有效,將緩存失效時間分散開,在設置過期時間時加上一個隨機值
2 做二級緩存
先請求一級緩存,若請求不到,再請求二級緩存。一級緩存和二級緩存數據一樣,但是二級緩存比一級緩存過期時間要稍長一點。
3 加鎖或排隊
通過加鎖或排隊控制請求DB並寫入緩存的線程數,這樣的性能不高
4 緩存標記
比如實際設置了key的過期時間爲60分鐘,給他一個緩存過期標記爲30分鐘,在到達30分鐘時,後臺有一個線程去更新這個緩存key。
三、緩存擊穿
緩存失效時,在這個時間節點上,這個數據被超高併發訪問,就都去請求DB了,DB被壓垮
緩存擊穿解決方案
1 使用互斥鎖
在緩存失效去請求DB前,先設置一個互斥鎖,當從DB中拿回數據時,將數據寫入緩存,再釋放鎖。多線程中誰先拿到鎖,誰去做DB請求,待釋放鎖之後,其他線程就可以直接拿緩存中的數據了。
2 永遠不過期
- ‘物理’不過期,即不設置過期時間
- ‘邏輯’不過期,在key對應的value中存上一份過期時間,當發現這個數過期時,通過異步進程去更新緩存