緩存穿透
概述
緩存穿透是指用戶請(qǐng)求的數(shù)據(jù)在緩存中不存在即沒有命中,同時(shí)在數(shù)據(jù)庫中也不存在,導(dǎo)致用戶每次請(qǐng)求該數(shù)據(jù)都要去數(shù)據(jù)庫中查詢一遍。如果有惡意攻擊者不斷請(qǐng)求系統(tǒng)中不存在的數(shù)據(jù),會(huì)導(dǎo)致短時(shí)間內(nèi)大量的請(qǐng)求落在數(shù)據(jù)庫上,造成數(shù)據(jù)庫壓力過大,甚至導(dǎo)致數(shù)據(jù)庫承受不住而宕機(jī)崩潰。
解決方案
使用布隆過濾器
布隆過濾器是一種數(shù)據(jù)結(jié)構(gòu),對(duì)所有可能查詢的參數(shù)以hash形式存儲(chǔ),在控制層先進(jìn)行校驗(yàn),不符合則丟棄,從而避免了對(duì)底層存儲(chǔ)系統(tǒng)的查詢壓力。

緩存空對(duì)象
當(dāng)存儲(chǔ)層不命中后,即使返回的空對(duì)象也將其緩存起來,同時(shí)設(shè)置一個(gè)過期時(shí)間【極短】,之后再訪問這個(gè)數(shù)據(jù)將會(huì)從緩存中獲取,保護(hù)了后端數(shù)據(jù)。
這種方法存在的問題:
- 如果空值能被緩存起來,這就意味著需要更多的空間來存儲(chǔ)很多空值的鍵。
- 即使對(duì)空值設(shè)置了過期時(shí)間,還是會(huì)存在緩存層和存儲(chǔ)層的數(shù)據(jù)會(huì)有一段時(shí)間數(shù)據(jù)的不一致,這對(duì)于需要保持?jǐn)?shù)據(jù)一致性的業(yè)務(wù)會(huì)有影響。
緩存擊穿
概述
緩存擊穿:是指一個(gè)key非常熱點(diǎn),在不停的扛著大并發(fā),大并發(fā)集中對(duì)這一個(gè)點(diǎn)進(jìn)行訪問,當(dāng)這個(gè)key在失效的瞬間,持續(xù)的大并發(fā)就穿破緩存,直接請(qǐng)求數(shù)據(jù)庫,就像在一個(gè)屏障上鑿開一個(gè)洞。
當(dāng)某個(gè)key在過期的瞬間,有大量的請(qǐng)求并發(fā)訪問,這類數(shù)據(jù)一般是熱點(diǎn)數(shù)據(jù),由于緩存過期,會(huì)同時(shí)訪問數(shù)據(jù)庫來查詢最新數(shù)據(jù),并且會(huì)寫緩存,會(huì)導(dǎo)致數(shù)據(jù)庫瞬間壓力過大。
解決方案
設(shè)置熱點(diǎn)數(shù)據(jù)永不過期
- 物理不過期:針對(duì)熱點(diǎn)key不設(shè)置過期時(shí)間
- 邏輯過期:把過期時(shí)間存在key對(duì)應(yīng)的value里,如果發(fā)現(xiàn)要過期了,通過一個(gè)后臺(tái)的異步線程進(jìn)行緩存的構(gòu)建。
加互斥鎖
分布式鎖:使用分布式鎖,保證對(duì)于每個(gè)key同時(shí)只有一個(gè)線程去查詢后端服務(wù),其他線程沒有獲得分布式鎖的權(quán)限,因此只需要等待即可。這種方式會(huì)阻塞其他的線程,此時(shí)系統(tǒng)的吞吐量會(huì)下降。
緩存雪崩
概念
緩存雪崩是指在某一個(gè)時(shí)間段,緩存集中過期。Redis宕機(jī)。
解決方案
Redis高可用
可以使用 主從+哨兵,Redis集群來避免Redis全盤崩潰的情況。(異地多活)
限流降級(jí)
在緩存失效后,通過加鎖或者隊(duì)列來控制數(shù)據(jù)庫寫緩存的線程數(shù)量。比如對(duì)某個(gè)key只允許一個(gè)線程查詢數(shù)據(jù)和寫緩存,其他線程等待。
數(shù)據(jù)預(yù)熱
數(shù)據(jù)預(yù)熱的含義就是在系統(tǒng)正式部署之前,我先把可能的數(shù)據(jù)先預(yù)先訪問一遍,這樣部分可能大量訪問的數(shù)據(jù)就會(huì)加載到緩存中,在即將發(fā)生大并發(fā)訪問前手動(dòng)觸發(fā)加載緩存不同的key,設(shè)置不同的過期時(shí)間,讓緩存失效時(shí)間盡量均勻。