Redis常見穿透問題、擊穿問題、雪崩問題解決方案
穿透問題
定義
Redis 緩存穿透指的是大量請(qǐng)求Redis緩存時(shí),查找不到對(duì)應(yīng)key,導(dǎo)致請(qǐng)求每次都會(huì)觸發(fā)查詢數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫壓力過大。如果請(qǐng)求量大的時(shí)候極有可能壓垮數(shù)據(jù)庫。
解決方案
- 做好參數(shù)校驗(yàn),無效的請(qǐng)求直接返回,只能避免一部分情況,攻擊者總是可以找到一些沒有覆蓋的情況。
- 如果一個(gè)查詢返回的數(shù)據(jù)為空(不管是數(shù)據(jù)不存在,還是系統(tǒng)故障),我們?nèi)匀话堰@個(gè)空結(jié)果進(jìn)行緩存,但它的過期時(shí)間會(huì)很短,最長(zhǎng)不超過五分鐘。
- 推薦:采用布隆過濾器,將所有可能存在的數(shù)據(jù)哈希到一個(gè)足夠大的bitmap中,一個(gè)一定不存在的數(shù)據(jù)會(huì)被這個(gè)bitmap攔截掉,從而避免了對(duì)底層存儲(chǔ)系統(tǒng)的查詢壓力。
擊穿問題
定義
某個(gè)緩存的key失效,導(dǎo)致大量的請(qǐng)求全部轉(zhuǎn)向查詢數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫壓力過大。
解決方案
- 對(duì)熱點(diǎn)key設(shè)置永不過期或提前預(yù)熱數(shù)據(jù)
- 加互斥鎖,緩存中沒有熱點(diǎn)key對(duì)應(yīng)的數(shù)據(jù)時(shí),由獲得鎖的線程去讀取數(shù)據(jù)庫然后設(shè)置緩存,沒有獲得鎖的請(qǐng)求等待100ms,再重新去緩存取數(shù)據(jù)。
- 接口限流與熔斷,降級(jí)。重要的接口一定要做好限流策略,防止用戶惡意刷接口,同時(shí)要降級(jí)準(zhǔn)備,當(dāng)接口中的某些服務(wù)不可用時(shí)候,進(jìn)行熔斷,失敗快速返回機(jī)制。
雪崩問題
定義
緩存雪崩主要指的是短時(shí)間內(nèi)大量key失效,導(dǎo)致所有請(qǐng)求全部轉(zhuǎn)向數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫壓力過大。
解決方案
- 在設(shè)置緩存事件時(shí)加隨機(jī)值,避免緩存扎堆失效。
- 可以把緩存層設(shè)計(jì)成高可用的,個(gè)別節(jié)點(diǎn)宕掉,依然可以提供服務(wù)。利用sentinel或cluster實(shí)現(xiàn)。
- 雙緩存機(jī)制,緩存A的失效時(shí)間為20分鐘,緩存B沒有失效時(shí)間,從緩存A讀取數(shù)據(jù),緩存A中沒有時(shí),去緩存B中讀取數(shù)據(jù),并且啟動(dòng)一個(gè)異步線程來更新緩存A。
- 加鎖排隊(duì)(容易造成堵塞,不推薦)