關(guān)于Redis的緩存穿透問題
1. 緩存穿透的理解
緩存穿透是指客戶端請求的數(shù)據(jù)在緩存中和數(shù)據(jù)庫中都不存在,這樣緩存永遠(yuǎn)不會生效,這些請求都會打到數(shù)據(jù)庫。
2. 常見的解決方案有兩種:
- 1.緩存空對象
- 優(yōu)點(diǎn):實(shí)現(xiàn)簡單,維護(hù)方便
- 缺點(diǎn):
- 額外的內(nèi)存消耗
- 可能造成短期的不一致
- 2.布隆過濾
- 優(yōu)點(diǎn):內(nèi)存占用較少,沒有多余key
- 缺點(diǎn):
- 實(shí)現(xiàn)復(fù)雜
- 存在誤判可能
**緩存空對象思路分析:**當(dāng)我們客戶端訪問不存在的數(shù)據(jù)時(shí),先請求redis,但是此時(shí)redis中沒有數(shù)據(jù),此時(shí)會訪問到數(shù)據(jù)庫,但是數(shù)據(jù)庫中也沒有數(shù)據(jù),這個(gè)數(shù)據(jù)穿透了緩存,直擊數(shù)據(jù)庫,我們都知道數(shù)據(jù)庫能夠承載的并發(fā)不如redis這么高,如果大量的請求同時(shí)過來訪問這種不存在的數(shù)據(jù),這些請求就都會訪問到數(shù)據(jù)庫,簡單的解決方案就是哪怕這個(gè)數(shù)據(jù)在數(shù)據(jù)庫中也不存在,我們也把這個(gè)數(shù)據(jù)存入到redis中去,這樣,下次用戶過來訪問這個(gè)不存在的數(shù)據(jù),那么在redis中也能找到這個(gè)數(shù)據(jù)就不會進(jìn)入到緩存了
3. 布隆過濾:
布隆過濾器其實(shí)采用的是哈希思想來解決這個(gè)問題,通過一個(gè)龐大的二進(jìn)制數(shù)組,走哈希思想去判斷當(dāng)前這個(gè)要查詢的這個(gè)數(shù)據(jù)是否存在,如果布隆過濾器判斷存在,則放行,這個(gè)請求會去訪問redis,哪怕此時(shí)redis中的數(shù)據(jù)過期了,但是數(shù)據(jù)庫中一定存在這個(gè)數(shù)據(jù),在數(shù)據(jù)庫中查詢出來這個(gè)數(shù)據(jù)后,再將其放入到redis中,
假設(shè)布隆過濾器判斷這個(gè)數(shù)據(jù)不存在,則直接返回
這種方式優(yōu)點(diǎn)在于節(jié)約內(nèi)存空間,存在誤判,誤判原因在于:布隆過濾器走的是哈希思想,只要哈希思想,就可能存在哈希沖突

4. 編碼解決查詢的緩存穿透問題:
核心思路如下:
在原來的邏輯中,我們?nèi)绻l(fā)現(xiàn)這個(gè)數(shù)據(jù)在mysql中不存在,直接就返回404了,這樣是會存在緩存穿透問題的
現(xiàn)在的邏輯中:如果這個(gè)數(shù)據(jù)不存在,我們不會返回404 ,還是會把這個(gè)數(shù)據(jù)寫入到Redis中,并且將value設(shè)置為空,當(dāng)再次發(fā)起查詢時(shí),我們?nèi)绻l(fā)現(xiàn)命中之后,判斷這個(gè)value是否是null,如果是null,則是之前寫入的數(shù)據(jù),證明是緩存穿透數(shù)據(jù),如果不是,則直接返回?cái)?shù)據(jù)。

小總結(jié):
緩存穿透產(chǎn)生的原因是什么?
- 用戶請求的數(shù)據(jù)在緩存中和數(shù)據(jù)庫中都不存在,不斷發(fā)起這樣的請求,給數(shù)據(jù)庫帶來巨大壓力
緩存穿透的解決方案有哪些?
- 緩存null值
- 布隆過濾
- 增強(qiáng)id的復(fù)雜度,避免被猜測id規(guī)律
- 做好數(shù)據(jù)的基礎(chǔ)格式校驗(yàn)
- 加強(qiáng)用戶權(quán)限校驗(yàn)
- 做好熱點(diǎn)參數(shù)的限流
相關(guān)文章
IDEA創(chuàng)建的maven項(xiàng)目中pom.xml增加新依賴無效問題及解決
在IDEA中,解決maven項(xiàng)目pom.xml增加依賴但外部庫未更新的問題,可以通過設(shè)置"構(gòu)建腳本更改后同步項(xiàng)目"選項(xiàng)為"任何更改",然后刷新Maven項(xiàng)目來解決2025-01-01
SpringBoot創(chuàng)建RSocket服務(wù)器的全過程記錄
RSocket應(yīng)用層協(xié)議支持 Reactive Streams語義, 例如:用RSocket作為HTTP的一種替代方案。這篇文章主要給大家介紹了關(guān)于SpringBoot創(chuàng)建RSocket服務(wù)器的相關(guān)資料,需要的朋友可以參考下2021-05-05
java實(shí)現(xiàn)Flappy Bird游戲源代碼
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)Flappy Bird游戲源代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12
springboot swagger 接口文檔分組展示功能實(shí)現(xiàn)
這篇文章主要介紹了springboot swagger 接口文檔分組展示功能實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-03-03
使用Mybatis遇到的坑之Integer類型參數(shù)的解讀
這篇文章主要介紹了使用Mybatis遇到的坑之Integer類型參數(shù)的解讀,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
Maven清理java項(xiàng)目中未使用到 jar 依賴包的方法
本文主要介紹了Maven清理java項(xiàng)目中未使用到 jar 依賴包的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-02-02

