業(yè)內(nèi)人士都聽說過緩存擊穿與緩存雪崩。緩存擊穿它是指某一key經(jīng)常被用戶特別關(guān)注經(jīng)常被查詢,而恰好此時(shí)間節(jié)點(diǎn)對(duì)Key有大量的并發(fā)請(qǐng)求過來,龐大數(shù)量的請(qǐng)求打到db,這些請(qǐng)求有坑你會(huì)直接擊穿高速緩存,數(shù)據(jù)庫(kù)的訪問壓力也會(huì)瞬間被擊穿。緩存雪崩它是指緩存中的大量數(shù)據(jù)到了過期時(shí)間,這種巨大的數(shù)據(jù)導(dǎo)致了數(shù)據(jù)庫(kù)壓力過大,甚至down機(jī)。下面我們就來詳細(xì)介紹一下緩存擊穿和緩存雪崩。
一般來說,緩存穿透的場(chǎng)景發(fā)生在故意攻擊的場(chǎng)景下;比如說,本來查詢意見商品的序號(hào)是正數(shù),但是請(qǐng)求方總是請(qǐng)求大量的負(fù)數(shù)過來,導(dǎo)致緩存無效,全部流量都打在了數(shù)據(jù)庫(kù)中,如果某一時(shí)刻流量過大,則會(huì)導(dǎo)致數(shù)據(jù)庫(kù)崩潰;緩存雪崩是指緩存中數(shù)據(jù)大批量到過期時(shí)間,而查詢數(shù)據(jù)量巨大,引起數(shù)據(jù)庫(kù)壓力過大甚至down機(jī)。緩存擊穿是指熱點(diǎn)key在某個(gè)時(shí)間點(diǎn)過期的時(shí)候,而恰好在這個(gè)時(shí)間點(diǎn)對(duì)這個(gè)Key有大量的并發(fā)請(qǐng)求過來,從而大量的請(qǐng)求打到db。
一、緩存擊穿:如果數(shù)據(jù)庫(kù)中有緩存,CPU中有緩存,那么模擬真實(shí)數(shù)據(jù)的原因就更多了。我們應(yīng)該避免在不需要緩存的情況下緩存和合理的模擬。在項(xiàng)目的實(shí)際開發(fā)和部署過程中,為了減輕db的壓力,必須使用Nosql作為中間介質(zhì),以減少數(shù)據(jù)庫(kù)的I/O操作,從而提高系統(tǒng)訪問效率。作為最常用的緩存處理工具,Redis在使用過程中必須對(duì)緩存穿透、緩存擊穿和緩存雪崩有詳細(xì)的了解。高速緩存破壞是指key經(jīng)常被查詢,用戶經(jīng)常關(guān)注。正如熟客或key經(jīng)常不訪問一樣,用戶非常喜歡它。但是在這個(gè)時(shí)候,如果key在高速緩存到期時(shí)失效或者是冷門key,那么在這個(gè)時(shí)候突然出現(xiàn)了大量的訪問請(qǐng)求,這就會(huì)導(dǎo)致大并發(fā)請(qǐng)求直接穿透高速緩存,請(qǐng)求數(shù)據(jù)庫(kù),瞬間增加訪問數(shù)據(jù)庫(kù)的壓力。
歸納起來:緩存破壞有兩個(gè)原因。
1、一個(gè)冷門key突然被大量用戶要求訪問。
2、一款熱門key,緩存時(shí)間正好過期,此時(shí)有大量的用戶訪問。
我們的業(yè)務(wù)通常會(huì)經(jīng)常訪問幾個(gè)數(shù)據(jù),比如秒殺活動(dòng),這些頻繁訪問的數(shù)據(jù)被稱為熱點(diǎn)數(shù)據(jù)。如果緩存中的熱點(diǎn)數(shù)據(jù)過期,此時(shí)需要大量訪問熱點(diǎn)數(shù)據(jù),則無法從緩存中讀取。如果直接訪問數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)很容易被高并發(fā)性要求沖走,這就是緩存損壞的問題。有關(guān)緩存擊穿的問題:我們常用的解決辦法是加鎖。在key過期時(shí),在key想要查詢數(shù)據(jù)庫(kù)時(shí)添加一把鎖,此時(shí)只能讓第一個(gè)請(qǐng)求查詢數(shù)據(jù)庫(kù),然后將從數(shù)據(jù)庫(kù)中查詢到的值存儲(chǔ)在其他相同的key中,這樣就可以直接從緩存中獲得。
二、緩存雪崩:緩存雪崩是指當(dāng)數(shù)據(jù)緩存到期時(shí),大量的查詢數(shù)據(jù)會(huì)導(dǎo)致數(shù)據(jù)庫(kù)壓力過大,甚至down機(jī)。不像緩存擊穿,緩存擊穿是指同一數(shù)據(jù)的并發(fā)查詢,緩存雪崩是不同數(shù)據(jù)的過期時(shí)間,很多數(shù)據(jù)無法查詢,從而查詢數(shù)據(jù)庫(kù)。
理由:
Redis突然停止了。
大部分?jǐn)?shù)據(jù)無效。
舉例來說,我們基本上都經(jīng)歷過購(gòu)物狂歡,假辦了23:00-24:00的商品骨折促銷活動(dòng)。程序小哥哥在23:00將商家骨折的商品放入緩存中,并通過redis的expire設(shè)置了一個(gè)小時(shí)的過期時(shí)間。在此期間,許多用戶會(huì)訪問這些商品信息、購(gòu)買等。但正好在24:00時(shí),碰巧有許多用戶正在訪問這些商品,此時(shí)訪問這些商品就會(huì)落到數(shù)據(jù)庫(kù)上,造成數(shù)據(jù)庫(kù)承受著巨大的壓力,稍有不慎就會(huì)直接導(dǎo)致數(shù)據(jù)庫(kù)。
緩存雪崩有以下解決方案:
1、redis高度可用。
redis有可能掛掉,增加一些redis實(shí)例(一主多從或多主多從),這樣一個(gè)掛掉之后其他的就可以繼續(xù)工作了,實(shí)際上就是建立了一個(gè)集群。
2、限制流量降級(jí)。
緩存失效后,通過鎖定或隊(duì)列控制讀取數(shù)據(jù)庫(kù)中緩存的線程。在某些密鑰中,只有一個(gè)線程可以查詢數(shù)據(jù)和寫入緩存,其他線程可以等待。
3、數(shù)據(jù)預(yù)熱。
資料加熱是指在正式部署之前,我會(huì)提前訪問可能的數(shù)據(jù),這樣可能會(huì)將大量訪問的數(shù)據(jù)加載到緩存中。在進(jìn)行大并發(fā)訪問之前,手動(dòng)觸發(fā)加載緩存。
4、不同的過期時(shí)間。
設(shè)定不同的過期時(shí)間,使緩存故障時(shí)間盡可能均勻。
以上我們分享了緩存擊穿和緩存雪崩的詳細(xì)介紹了。一般來講我們?cè)O(shè)計(jì)一個(gè)緩存系統(tǒng),必須考慮的問題就是緩存穿透,緩存擊穿以及失效時(shí)的雪崩效應(yīng),如果您對(duì)相關(guān)知識(shí)感興趣,可以繼續(xù)關(guān)注中培偉業(yè)。