自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

緩存穿透、緩存雪崩、緩存擊穿?再也不怕了,你隨便問(wèn)吧!

存儲(chǔ) 存儲(chǔ)架構(gòu)
本文介紹了在使用緩存時(shí)經(jīng)常會(huì)遇到的三種異常情況:緩存穿透、緩存雪崩和緩存擊穿。三種異常情況從根本上來(lái)說(shuō)都是因?yàn)楸緫?yīng)該訪問(wèn)緩存的,但是緩存不存在或服務(wù)異常,導(dǎo)致流量直接進(jìn)入了數(shù)據(jù)庫(kù)層面。

?背景

在現(xiàn)代軟件架構(gòu)中,緩存的應(yīng)用已經(jīng)非常普及。緩存的使用在面試和實(shí)踐中都是避不開(kāi)的硬技能、硬知識(shí),如果你說(shuō)還不太熟悉緩存的使用,可能都不好意思說(shuō)自己是程序員。

在上篇文章《??如果不知道這4種緩存模式,敢說(shuō)懂緩存嗎???》中,我們介紹了緩存使用的四種策略,如果能夠結(jié)合不同的場(chǎng)景進(jìn)行靈活運(yùn)用,你已經(jīng)超過(guò)了大多數(shù)人。畢竟,那四種策略,很多開(kāi)發(fā)多年的人可能都沒(méi)聽(tīng)說(shuō)過(guò)。

這篇文章,帶大家進(jìn)一步學(xué)習(xí)在緩存使用中不得不考慮三個(gè)特殊場(chǎng)景:緩存穿透、緩存雪崩、緩存擊穿。

為什么說(shuō)不得不考慮?因?yàn)槿绻豢紤]這些特殊的場(chǎng)景,在高并發(fā)的情況可能直接導(dǎo)致系統(tǒng)崩潰。下面以常見(jiàn)的Redis緩存組件為例來(lái)講解這三種場(chǎng)景及解決方案。

大前提

當(dāng)我們使用緩存時(shí),目標(biāo)通常有兩個(gè):第一,提升響應(yīng)效率和并發(fā)量;第二,減輕數(shù)據(jù)庫(kù)的壓力。

而本文中所提到的這三種場(chǎng)景:緩存穿透、緩存雪崩和緩存擊穿的發(fā)生,都是因?yàn)樵谀承┨厥馇闆r下,緩存失去了預(yù)期的功能所致。

當(dāng)緩存失效或沒(méi)有抵擋住流量,流量直接涌入到數(shù)據(jù)庫(kù),在高并發(fā)的情況下,可能直接擊垮數(shù)據(jù)庫(kù),導(dǎo)致整個(gè)系統(tǒng)崩潰。

這就是我們需要知道的大前提,而緩存穿透、緩存雪崩和緩存擊穿,只不過(guò)是在這個(gè)大前提下的不同場(chǎng)景的細(xì)分場(chǎng)景而已。

緩存穿透

大多數(shù)情況,緩存可以減少數(shù)據(jù)庫(kù)的查詢,提升系統(tǒng)性能。

通常流程是:一個(gè)請(qǐng)求過(guò)來(lái),先查詢是否在緩存當(dāng)中,如果緩存中存在,則直接返回。如果緩存中不存在對(duì)應(yīng)的數(shù)據(jù),則檢索數(shù)據(jù)庫(kù),如果數(shù)據(jù)庫(kù)中存在對(duì)應(yīng)的數(shù)據(jù),則更新緩存并返回結(jié)果。如果數(shù)據(jù)庫(kù)中也不存在對(duì)應(yīng)的數(shù)據(jù),則返回空或錯(cuò)誤。

緩存穿透(cache penetration)是用戶訪問(wèn)的數(shù)據(jù)既不在緩存當(dāng)中,也不在數(shù)據(jù)庫(kù)中。出于容錯(cuò)的考慮,如果從底層數(shù)據(jù)庫(kù)查詢不到數(shù)據(jù),則不寫入緩存。這就導(dǎo)致每次請(qǐng)求都會(huì)到底層數(shù)據(jù)庫(kù)進(jìn)行查詢,緩存也失去了意義。當(dāng)高并發(fā)或有人利用不存在的Key頻繁攻擊時(shí),數(shù)據(jù)庫(kù)的壓力驟增,甚至崩潰,這就是緩存穿透問(wèn)題。

圖片

緩存穿透

緩存穿透發(fā)生的場(chǎng)景一般有兩類:

  • 原來(lái)數(shù)據(jù)是存在的,但由于某些原因(誤刪除、主動(dòng)清理等)在緩存和數(shù)據(jù)庫(kù)層面被刪除了,但前端或前置的應(yīng)用程序依舊保有這些數(shù)據(jù);
  • 惡意攻擊行為,利用不存在的Key或者惡意嘗試導(dǎo)致產(chǎn)生大量不存在的業(yè)務(wù)數(shù)據(jù)請(qǐng)求。

緩存穿透通常有四種解決方案,我們逐一介紹分析。

方案一:緩存空值(null)或默認(rèn)值

分析業(yè)務(wù)請(qǐng)求,如果是正常業(yè)務(wù)請(qǐng)求時(shí)發(fā)生緩存穿透現(xiàn)象,可針對(duì)相應(yīng)的業(yè)務(wù)數(shù)據(jù),在數(shù)據(jù)庫(kù)查詢不存在時(shí),將其緩存為空值(null)或默認(rèn)值。需要注意的是,針對(duì)空值的緩存失效時(shí)間不宜過(guò)長(zhǎng),一般設(shè)置為5分鐘之內(nèi)。當(dāng)數(shù)據(jù)庫(kù)被寫入或更新該key的新數(shù)據(jù)時(shí),緩存必須同時(shí)被刷新,避免數(shù)據(jù)不一致。

方案二:業(yè)務(wù)邏輯前置校驗(yàn)

在業(yè)務(wù)請(qǐng)求的入口處進(jìn)行數(shù)據(jù)合法性校驗(yàn),檢查請(qǐng)求參數(shù)是否合理、是否包含非法值、是否惡意請(qǐng)求等,提前有效阻斷非法請(qǐng)求。比如,根據(jù)年齡查詢時(shí),請(qǐng)求的年齡為-10歲,這顯然是不合法的請(qǐng)求參數(shù),直接在參數(shù)校驗(yàn)時(shí)進(jìn)行判斷返回。

方案三:使用布隆過(guò)濾器請(qǐng)求白名單

在寫入數(shù)據(jù)時(shí),使用布隆過(guò)濾器進(jìn)行標(biāo)記(相當(dāng)于設(shè)置白名單),業(yè)務(wù)請(qǐng)求發(fā)現(xiàn)緩存中無(wú)對(duì)應(yīng)數(shù)據(jù)時(shí),可先通過(guò)查詢布隆過(guò)濾器判斷數(shù)據(jù)是否在白名單內(nèi),如果不在白名單內(nèi),則直接返回空或失敗。

方案四:用戶黑名單限制

當(dāng)發(fā)生異常情況時(shí),實(shí)時(shí)監(jiān)控訪問(wèn)的對(duì)象和數(shù)據(jù),分析用戶行為,針對(duì)故意請(qǐng)求、爬蟲或攻擊者,進(jìn)行特定用戶的限制;

當(dāng)然,可能針對(duì)緩存穿透的情況,也有可能是其他的原因引起,可以針對(duì)具體情況,采用對(duì)應(yīng)的措施。

緩存雪崩

在使用緩存時(shí),通常會(huì)對(duì)緩存設(shè)置過(guò)期時(shí)間,一方面目的是保持緩存與數(shù)據(jù)庫(kù)數(shù)據(jù)的一致性,另一方面是減少冷緩存占用過(guò)多的內(nèi)存空間。

但當(dāng)緩存中大量熱點(diǎn)緩存采用了相同的實(shí)效時(shí)間,就會(huì)導(dǎo)致緩存在某一個(gè)時(shí)刻同時(shí)實(shí)效,請(qǐng)求全部轉(zhuǎn)發(fā)到數(shù)據(jù)庫(kù),從而導(dǎo)致數(shù)據(jù)庫(kù)壓力驟增,甚至宕機(jī)。從而形成一系列的連鎖反應(yīng),造成系統(tǒng)崩潰等情況,這就是緩存雪崩(Cache Avalanche)。

圖片

緩存雪崩

上面講到的是熱點(diǎn)key同時(shí)失效的場(chǎng)景,另外就是由于某些原因?qū)е戮彺娣?wù)宕機(jī)、掛掉或不響應(yīng),也同樣會(huì)導(dǎo)致流量直接轉(zhuǎn)移到數(shù)據(jù)庫(kù)。

所以,緩存雪崩的場(chǎng)景通常有兩個(gè):

  • 大量熱點(diǎn)key同時(shí)過(guò)期;
  • 緩存服務(wù)故障;

緩存雪崩的解決方案:

  • 通常的解決方案是將key的過(guò)期時(shí)間后面加上一個(gè)隨機(jī)數(shù)(比如隨機(jī)1-5分鐘),讓key均勻的失效。
  • 考慮用隊(duì)列或者鎖的方式,保證緩存單線程寫,但這種方案可能會(huì)影響并發(fā)量。
  • 熱點(diǎn)數(shù)據(jù)可以考慮不失效,后臺(tái)異步更新緩存,適用于不嚴(yán)格要求緩存一致性的場(chǎng)景。
  • 雙key策略,主key設(shè)置過(guò)期時(shí)間,備key不設(shè)置過(guò)期時(shí)間,當(dāng)主key失效時(shí),直接返回備key值。
  • 構(gòu)建緩存高可用集群(針對(duì)緩存服務(wù)故障情況)。
  • 當(dāng)緩存雪崩發(fā)生時(shí),服務(wù)熔斷、限流、降級(jí)等措施保障。

緩存擊穿

緩存雪崩是指只大量熱點(diǎn)key同時(shí)失效的情況,如果是單個(gè)熱點(diǎn)key,在不停的扛著大并發(fā),在這個(gè)key失效的瞬間,持續(xù)的大并發(fā)請(qǐng)求就會(huì)擊破緩存,直接請(qǐng)求到數(shù)據(jù)庫(kù),好像蠻力擊穿一樣。這種情況就是緩存擊穿(Cache Breakdown)。

圖片

緩存擊穿

從定義上可以看出,緩存擊穿和緩存雪崩很類似,只不過(guò)是緩存擊穿是一個(gè)熱點(diǎn)key失效,而緩存雪崩是大量熱點(diǎn)key失效。因此,可以將緩存擊穿看作是緩存雪崩的一個(gè)子集。

緩存擊穿的解決方案:

  • 使用互斥鎖(Mutex Key),只讓一個(gè)線程構(gòu)建緩存,其他線程等待構(gòu)建緩存執(zhí)行完畢,重新從緩存中獲取數(shù)據(jù)。單機(jī)通過(guò)synchronized或lock來(lái)處理,分布式環(huán)境采用分布式鎖。
  • 熱點(diǎn)數(shù)據(jù)不設(shè)置過(guò)期時(shí)間,后臺(tái)異步更新緩存,適用于不嚴(yán)格要求緩存一致性的場(chǎng)景。
  • ”提前“使用互斥鎖(Mutex Key):在value內(nèi)部設(shè)置一個(gè)比緩存(Redis)過(guò)期時(shí)間短的過(guò)期時(shí)間標(biāo)識(shí),當(dāng)異步線程發(fā)現(xiàn)該值快過(guò)期時(shí),馬上延長(zhǎng)內(nèi)置的這個(gè)時(shí)間,并重新從數(shù)據(jù)庫(kù)加載數(shù)據(jù),設(shè)置到緩存中去。

小結(jié)

本文介紹了在使用緩存時(shí)經(jīng)常會(huì)遇到的三種異常情況:緩存穿透、緩存雪崩和緩存擊穿。

三種異常情況從根本上來(lái)說(shuō)都是因?yàn)楸緫?yīng)該訪問(wèn)緩存的,但是緩存不存在或服務(wù)異常,導(dǎo)致流量直接進(jìn)入了數(shù)據(jù)庫(kù)層面。

其中緩存雪崩和緩存擊穿是因?yàn)閿?shù)據(jù)不存在(或服務(wù)異常獲取不到),導(dǎo)致大量請(qǐng)求訪問(wèn)數(shù)據(jù)庫(kù),從而導(dǎo)致數(shù)據(jù)庫(kù)壓力驟增,甚至崩潰。

而緩存穿透則是由于數(shù)據(jù)本身就不存在,導(dǎo)致緩存沒(méi)有進(jìn)行數(shù)據(jù)緩存,流量進(jìn)入數(shù)據(jù)庫(kù)層。

針對(duì)不同的緩存異常場(chǎng)景,可選擇不同的方案來(lái)進(jìn)行處理。當(dāng)然,除了上述方案,我們還可以限流、降級(jí)、熔斷等服務(wù)層的措施,也可以考慮數(shù)據(jù)庫(kù)層是否可以進(jìn)行橫向擴(kuò)展,當(dāng)緩存異常發(fā)生時(shí),確保數(shù)據(jù)庫(kù)能夠抗住流量,不至于讓整個(gè)系統(tǒng)崩潰。

責(zé)任編輯:武曉燕 來(lái)源: 程序新視界
相關(guān)推薦

2023-03-10 13:33:00

緩存穿透緩存擊穿緩存雪崩

2019-10-12 14:19:05

Redis數(shù)據(jù)庫(kù)緩存

2019-11-05 14:24:31

緩存雪崩框架

2021-06-05 09:01:01

Redis緩存雪崩緩存穿透

2020-03-16 14:57:24

Redis面試雪崩

2024-03-12 10:44:42

2022-05-27 07:57:20

緩存穿透緩存雪崩緩存擊穿

2022-03-08 00:07:51

緩存雪崩數(shù)據(jù)庫(kù)

2021-12-25 22:28:27

緩存穿透緩存擊穿緩存雪崩

2022-11-18 14:34:28

2023-11-10 14:58:03

2023-04-14 07:34:19

2020-10-13 07:44:40

緩存雪崩 穿透

2023-12-06 13:38:00

Redis緩存穿透緩存擊穿

2020-10-23 10:46:03

緩存雪崩擊穿

2020-03-05 09:09:18

緩存原因方案

2020-12-28 12:37:36

緩存擊穿穿透

2024-04-18 11:43:28

緩存數(shù)據(jù)庫(kù)Redis

2024-04-07 00:00:02

Redis雪崩緩存

2023-05-15 10:03:00

Redis緩存穿透
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)