Redis实战-缓存穿透、缓存雪崩、缓存击穿和缓存并发的区别和解决方案
正常處理流程
??客戶端請(qǐng)求正常的時(shí)候,先讀緩存,如果數(shù)據(jù)命中,則返回緩存的值;否則,把從存儲(chǔ)層中讀取出來的數(shù)據(jù)緩存至緩存,同時(shí)返回客戶端。但是,為了保證系統(tǒng)高可用和高性能,設(shè)計(jì)一個(gè)緩存系統(tǒng)時(shí)必須考慮的要素包括緩存穿透、緩存擊穿、緩存雪崩和緩存并發(fā)等。這里,小編給大家簡(jiǎn)明扼要地綜述一下它們的基本概念和解決策略。
緩存穿透
??基本概念:客戶端訪問緩存和數(shù)據(jù)庫(kù)中都沒有的數(shù)據(jù),如果系統(tǒng)不對(duì)其緩存,就出現(xiàn)了緩存穿透。流量大時(shí)會(huì)導(dǎo)致存儲(chǔ)層掛掉。
??簡(jiǎn)述:緩存中不存在的數(shù)據(jù)洪水猛獸般襲來,訪問穿透到存儲(chǔ)層。
??解決方案:
緩存空對(duì)象。
對(duì)于未命中緩存和存儲(chǔ)層的數(shù)據(jù),設(shè)置默認(rèn)值和五分鐘左右的有效期(有效期根據(jù)業(yè)務(wù)需要設(shè)置)。
使用布隆過濾器。
緩存擊穿
??基本概念:一個(gè)緩存key是熱點(diǎn)數(shù)據(jù),在不停的扛著大并發(fā),但過期那一刻持續(xù)的大并發(fā)就穿破緩存,導(dǎo)致存儲(chǔ)層請(qǐng)求量瞬間飆高。
??解決方案:
使用互斥鎖。
在發(fā)現(xiàn)緩存失效的時(shí)候(判斷拿出來的值為空),不是立即去請(qǐng)求DB,而是成功添加互斥鎖后再請(qǐng)求DB并回設(shè)緩存;否則,就重試查詢緩存的方法。提前使用互斥鎖。
在value內(nèi)部設(shè)置1個(gè)超時(shí)標(biāo)簽(timeout1),當(dāng)從cache讀取到timeout1發(fā)現(xiàn)它已經(jīng)過期的時(shí)候,馬上延長(zhǎng)timeout1并重新設(shè)置到cache,然后再?gòu)臄?shù)據(jù)庫(kù)加載數(shù)據(jù)并設(shè)置到cache中。
??緩存擊穿和緩存雪崩的區(qū)別在于前者針對(duì)某一個(gè)key,緩存雪崩則是針對(duì)很多key。緩存key在某個(gè)時(shí)間點(diǎn)過期的時(shí)候,恰好有大量的并發(fā)請(qǐng)求過來,這些請(qǐng)求發(fā)現(xiàn)緩存過期就從后端DB加載數(shù)據(jù)并回設(shè)到緩存,這個(gè)時(shí)候大并發(fā)的請(qǐng)求可能會(huì)瞬間把后端DB壓垮。
緩存雪崩
??基本概念:緩存服務(wù)器某個(gè)節(jié)點(diǎn)宕機(jī)或斷網(wǎng)或者在某一個(gè)時(shí)間段大量緩存集體失效,請(qǐng)求全部轉(zhuǎn)發(fā)到DB,DB壓力驟增而引起雪崩。
??解決方案:
使緩存過期時(shí)間呈泊松分布。
開啟緩存過期事件監(jiān)聽和異步更新策略。
監(jiān)聽到緩存過期時(shí),異步起一個(gè)線程去讀數(shù)據(jù)庫(kù),更新緩存。
修改Redis配置文件,開啟過期事件監(jiān)聽:使notify-keyspace-events的值為Ex。
緩存并發(fā)
??基本概念:多個(gè)redis的client同時(shí)set key引起的并發(fā)問題。其實(shí)redis自身就是單線程操作,多個(gè)client并發(fā)操作,按照先到先執(zhí)行的原則,先到的先執(zhí)行,其余的阻塞。當(dāng)然,另外的解決方案是把set操作放在隊(duì)列中使其串行化,必須一個(gè)一個(gè)的執(zhí)行。
Reference
https://baijiahao.baidu.com/s?id=1655304940308056733&wfr=spider&for=pc
總結(jié)
以上是生活随笔為你收集整理的Redis实战-缓存穿透、缓存雪崩、缓存击穿和缓存并发的区别和解决方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试题:Spring BeanFacto
- 下一篇: Java 验证电子邮箱是否合法