1、Redis雪崩怎么處理?
案例場(chǎng)景:目前電商熱點(diǎn)數(shù)據(jù)都會(huì)去做緩存 ,一般緩存都是定時(shí)任務(wù)去刷新,或者是查不到之后去更新的,定時(shí)任務(wù)刷新就有一個(gè)問題。假設(shè)所有熱點(diǎn)數(shù)據(jù)的Key都是0點(diǎn)失效,0點(diǎn)刷新的,剛好我在零點(diǎn)有個(gè)秒殺活動(dòng)有大量用戶涌入,假設(shè)當(dāng)時(shí)每秒 10000 個(gè)請(qǐng)求,本來緩存在可以扛住每秒 5000 個(gè)請(qǐng)求,但是0點(diǎn)時(shí)所有的Key都失效了。此時(shí) 1 秒 10000?個(gè)請(qǐng)求全部到了數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)必然扛不住就直接掛了。這個(gè)時(shí)候重啟數(shù)據(jù)庫(kù),又會(huì)新的流量給搞掛。這就是我理解的緩存雪崩。
處理方案:在批量往Redis存數(shù)據(jù)的時(shí)候,把每個(gè)Key的失效時(shí)間都加個(gè)隨機(jī)值,這樣可以保證數(shù)據(jù)不會(huì)在同一時(shí)間大面積失效。
如果Redis是集群部署,將熱點(diǎn)數(shù)據(jù)均勻分布在不同的Redis庫(kù)中也能避免全部失效的問題?;蛘咴O(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過期,有更新操作就更新緩存就好了
2、緩存穿透和擊穿與雪崩的區(qū)別?
緩存穿透是指緩存和數(shù)據(jù)庫(kù)中都沒有的數(shù)據(jù),而用戶不斷發(fā)起請(qǐng)求。例如我們數(shù)據(jù)庫(kù)的 id 都是1開始自增上去的,如發(fā)起id值為 -1 的數(shù)據(jù)請(qǐng)求。每次請(qǐng)求都能繞開Redis直接到數(shù)據(jù)庫(kù),但是數(shù)據(jù)庫(kù)也查不到,如果同一時(shí)間大量這樣的請(qǐng)求會(huì)導(dǎo)致數(shù)據(jù)庫(kù)壓力過大,嚴(yán)重會(huì)擊垮數(shù)據(jù)庫(kù)。
緩存雪崩是因?yàn)榫彺嬷械臄?shù)據(jù)同一時(shí)間大面積失效造成大量請(qǐng)求直接到了數(shù)據(jù)庫(kù)造成數(shù)據(jù)庫(kù)崩潰,而緩存擊穿是指一個(gè)Key非常熱點(diǎn),大量的請(qǐng)求對(duì)一個(gè)點(diǎn)進(jìn)行訪問時(shí)造成數(shù)據(jù)庫(kù)崩潰。
處理方案:
方案一:可以把不存在的key也設(shè)置緩存,并設(shè)置過期時(shí)間;
解決思路,盡量的把請(qǐng)求攔截到,不讓它去訪問數(shù)據(jù)庫(kù),那我們?cè)趺慈r截呢,比如說,當(dāng)拿一個(gè)不存在key訪問程序的時(shí)候,如果查詢數(shù)據(jù)庫(kù),不存在對(duì)應(yīng)的值,那我們也會(huì)給不存在的這個(gè)key 存入到緩存里面,并且可以設(shè)置緩存失效時(shí)間;比如說可以把對(duì)應(yīng)的key設(shè)置為null值存入到緩存里面,如果下次有相同的key來訪問的時(shí)候,在緩存失效之前,都是直接從緩存里面取;這樣就會(huì)把不必要的請(qǐng)求攔截下來;
方案二:使用redis或者zookeep提供的互斥鎖也可以解決緩存擊穿
這種方案是通過異步方式 去獲取緩存過程中,其他key 處于等待現(xiàn)象,必須等待第一個(gè)構(gòu)建完緩存之后,釋放鎖,其他人才能通過該key才能訪問數(shù)據(jù)