安裝兩個(gè)wordpressseozhun
文章目錄
- 1 文章概述
- 2 緩存穿透
- 2.1 什么是緩存穿透?
- 2.2 緩存穿透的解決方法
- 2.2.1 做好參數(shù)校驗(yàn)
- 2.2.2 緩存無效Key
- 2.2.3 使用布隆過濾器
- 2.2.4 接口限流
- 3 緩存擊穿
- 3.1 什么是緩存擊穿?
- 3.2 緩存擊穿的解決方法
- 3.2.1 調(diào)整熱點(diǎn)數(shù)據(jù)過期時(shí)間
- 3.2.2 熱點(diǎn)數(shù)據(jù)預(yù)熱
- 3.2.3 控制數(shù)據(jù)庫并發(fā)
- 4 緩存雪崩
- 4.1 什么是緩存雪崩?
- 4.2 緩存雪崩的解決方法
- 4.2.1 針對(duì)緩存服務(wù)不可用的情況
- 4.2.2 針對(duì)緩存大面積過期的情況
1 文章概述
在使用 Redis 作為緩存時(shí),緩存穿透、緩存擊穿和緩存雪崩是常見的問題,可能會(huì)影響系統(tǒng)性能和穩(wěn)定性。本文將深入探討這些問題的概念、產(chǎn)生原因、以及可能帶來的影響,并針對(duì)這些問題提供的解決方案,以幫助讀者更好地理解并解決這些挑戰(zhàn)。
2 緩存穿透
2.1 什么是緩存穿透?
緩存穿透問題: 大量且頻繁地請(qǐng)求緩存和數(shù)據(jù)庫中都不存在的數(shù)據(jù),由于緩存無法命中,這些請(qǐng)求都穿透緩存直接訪問數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫壓力暴增,影響系統(tǒng)性能。
緩存穿透可能發(fā)生的原因包括查詢參數(shù)異常、惡意攻擊、業(yè)務(wù)邏輯錯(cuò)誤等。如果惡意用戶或者攻擊者發(fā)送大量不存在于緩存中的請(qǐng)求,系統(tǒng)會(huì)不斷地去查詢數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫負(fù)載增加,甚至可能引起數(shù)據(jù)庫宕機(jī)。緩存穿透不僅影響系統(tǒng)性能,還可能暴露后端數(shù)據(jù)給未經(jīng)授權(quán)的用戶,造成安全隱患。
2.2 緩存穿透的解決方法
要解決緩存穿透問題,本質(zhì)就是要避免出現(xiàn)請(qǐng)求直接訪問數(shù)據(jù)庫的情況。
2.2.1 做好參數(shù)校驗(yàn)
解決緩存穿透,最基本的就是首先做好參數(shù)校驗(yàn),從系統(tǒng)入口處就拒絕掉非法的請(qǐng)求,一些不合法的參數(shù)請(qǐng)求直接拋出異常信息返回給客戶端。比如查詢的數(shù)據(jù)庫 id 不能小于 0、傳入的郵箱格式不對(duì)的時(shí)候直接返回錯(cuò)誤消息給客戶端等等。
2.2.2 緩存無效Key
做好參數(shù)校驗(yàn)只能拒絕掉不符合基本參數(shù)校驗(yàn)規(guī)則的請(qǐng)求,對(duì)于那些符合參數(shù)校驗(yàn)規(guī)則的無效請(qǐng)求則無能為力。
緩存無效Key方法指的是,在緩存和數(shù)據(jù)庫都查詢不到數(shù)據(jù)的時(shí)候,向緩存中插入一個(gè)空的數(shù)據(jù),并設(shè)置過期時(shí)間。這樣,當(dāng)下一次接收到相同請(qǐng)求時(shí),就可以直接從緩存中獲取到空數(shù)據(jù),而不需要查詢數(shù)據(jù)庫。
這種方式可以解決請(qǐng)求的 key 變化不頻繁的情況,如果黑客每次構(gòu)建不同的請(qǐng)求 key,不僅不能解決緩存穿透問題,還會(huì)導(dǎo)致 Redis 中緩存大量無效的 key 。很明顯,這種方案并不能從根本上解決此問題。如果非要用這種方式來解決穿透問題的話,盡量將無效的 key 的過期時(shí)間設(shè)置短一點(diǎn)。
2.2.3 使用布隆過濾器
布隆過濾器是一個(gè)非常神奇的數(shù)據(jù)結(jié)構(gòu),通過它我們可以非常方便地判斷一個(gè)給定數(shù)據(jù)是否存在于海量數(shù)據(jù)中。我們可以把它看作由二進(jìn)制向量(或者說位數(shù)組)和一系列隨機(jī)映射函數(shù)(哈希函數(shù))兩部分組成的數(shù)據(jù)結(jié)構(gòu)。相比于我們平時(shí)常用的 List、Map、Set 等數(shù)據(jù)結(jié)構(gòu),它占用空間更少并且效率更高,但是缺點(diǎn)是其返回的結(jié)果是概率性的,而不是非常準(zhǔn)確的。理論情況下添加到集合中的元素越多,誤報(bào)的可能性就越大。并且,存放在布隆過濾器的數(shù)據(jù)不容易刪除。
關(guān)于布隆過濾器的更多內(nèi)容,可以參考文章:布隆過濾器有什么用?什么原理?如何使用?
使用布隆過濾器解決緩存穿透問題的方法是:將所有可能存在的請(qǐng)求的值都存放在布隆過濾器中,當(dāng)用戶請(qǐng)求過來,先判斷用戶發(fā)來的請(qǐng)求的值是否存在于布隆過濾器中。不存在的話,直接返回請(qǐng)求參數(shù)錯(cuò)誤信息給客戶端,存在的話才會(huì)走后續(xù)流程。
2.2.4 接口限流
根據(jù)用戶或者 IP 對(duì)接口進(jìn)行限流,對(duì)于異常頻繁的訪問行為,還可以采取黑名單機(jī)制,例如將異常 IP 列入黑名單。
3 緩存擊穿
3.1 什么是緩存擊穿?
緩存擊穿問題: 緩存擊穿是指緩存中的某個(gè)熱點(diǎn)數(shù)據(jù)突然失效或過期,此時(shí)有大量并發(fā)請(qǐng)求同時(shí)訪問該數(shù)據(jù),導(dǎo)致這些請(qǐng)求無法從緩存中獲取數(shù)據(jù),而直接訪問數(shù)據(jù)庫,造成數(shù)據(jù)庫壓力劇增,甚至可能導(dǎo)致數(shù)據(jù)庫宕機(jī)。緩存擊穿通常發(fā)生在具有高并發(fā)讀取請(qǐng)求的熱點(diǎn)數(shù)據(jù)上。
3.2 緩存擊穿的解決方法
3.2.1 調(diào)整熱點(diǎn)數(shù)據(jù)過期時(shí)間
設(shè)置熱點(diǎn)數(shù)據(jù)永不過期或設(shè)置較長過期時(shí)間,避免熱點(diǎn)數(shù)據(jù)突然過期的情況,從根源上解決緩存擊穿問題!
應(yīng)該沒人會(huì)去隨便刪除熱點(diǎn)數(shù)據(jù)緩存吧?!
3.2.2 熱點(diǎn)數(shù)據(jù)預(yù)熱
針對(duì)熱點(diǎn)數(shù)據(jù)提前預(yù)熱,將其存入緩存中并設(shè)置合理的過期時(shí)間。這也能從根源上解決緩存擊穿問題!
比如在秒殺場景中:可以在秒殺活動(dòng)開始之前,將熱點(diǎn)數(shù)據(jù)加載到緩存中,并設(shè)置其過期時(shí)間在秒殺結(jié)束之后。
3.2.3 控制數(shù)據(jù)庫并發(fā)
在緩存失效時(shí)使用互斥鎖(Mutex)或者分布式鎖來保護(hù)數(shù)據(jù)庫查詢過程,只允許一個(gè)線程進(jìn)行數(shù)據(jù)庫查詢,其他線程等待查詢結(jié)果。
4 緩存雪崩
4.1 什么是緩存雪崩?
緩存雪崩問題: 緩存雪崩是指在緩存中存儲(chǔ)的大量數(shù)據(jù)同時(shí)失效或者過期,導(dǎo)致大量請(qǐng)求直接訪問數(shù)據(jù)庫獲取數(shù)據(jù),從而造成數(shù)據(jù)庫負(fù)載劇增,甚至引發(fā)系統(tǒng)崩潰的現(xiàn)象。
注意:緩存服務(wù)器宕機(jī)導(dǎo)致的緩存失效也算哦
4.2 緩存雪崩的解決方法
4.2.1 針對(duì)緩存服務(wù)不可用的情況
- 采用 Redis 集群,避免單機(jī)出現(xiàn)問題整個(gè)緩存服務(wù)都沒辦法使用。
- 限流,避免同時(shí)處理大量的請(qǐng)求。
- 采用多級(jí)緩存,例如本地緩存+Redis 緩存的組合,當(dāng) Redis 緩存出現(xiàn)問題時(shí),還可以從本地緩存中獲取到部分?jǐn)?shù)據(jù)。
4.2.2 針對(duì)緩存大面積過期的情況
- 設(shè)置緩存數(shù)據(jù)的過期時(shí)間隨機(jī)性,避免大量數(shù)據(jù)同時(shí)失效。
- 緩存永不失效(不太推薦,實(shí)用性太差)。
- 緩存預(yù)熱,也就是在程序啟動(dòng)后或運(yùn)行過程中,主動(dòng)將熱點(diǎn)數(shù)據(jù)加載到緩存中。