漫話:如何給女朋友解釋什么是緩存穿透、緩存擊穿、緩存雪崩?
周末在家面試,和候選人聊到Redis的問題,于是問了他一個問題:你知道緩存穿透、緩存擊穿和緩存雪崩嗎?他們之間的區(qū)別是什么?分別怎么解決嗎?
面試結(jié)束后,女朋友好像有很多問號,于是來問我。
緩存穿透
要把這個問題講清楚,先舉個例子。
一個女孩子去門店買口紅,到了門店之后被告知她想要的那個色號已經(jīng)沒有了。于是她要求店員去問總部還有沒有貨。總部發(fā)現(xiàn)這個色號也沒有了,于是女孩子就離開了。
過了一會另一個女孩子又來了,也想要購買同一個色號,店員就又總部問了一次。如此反復(fù)。
女孩子買口紅不僅需要門店幫忙查詢,還需要總部也進行盤貨。類似這種情況,在緩存領(lǐng)域有一個類似的概念叫做緩存穿透。
緩存穿透是指緩存服務(wù)器中沒有緩存數(shù)據(jù),數(shù)據(jù)庫中也沒有符合條件的數(shù)據(jù),導(dǎo)致業(yè)務(wù)系統(tǒng)每次都繞過緩存服務(wù)器查詢下游的數(shù)據(jù)庫,緩存服務(wù)器完全失去了其應(yīng)用的作用。
緩存空值
解決多次詢問總部的方法比較簡單,如果口紅門店在幫第一個女孩子查詢之后,就記錄下來這個色號已經(jīng)沒有了,下次其他女孩再來問這個色號的時候,直接告訴她沒貨了。
這樣就可以避免每次都驚動總部了。
在緩存中,之所以會發(fā)生穿透,就是因為緩存沒有對那些不存在的值得Key緩存下來,從而導(dǎo)致每次查詢都要請求到數(shù)據(jù)庫。
那么我們就可以為這些key對應(yīng)的值設(shè)置為null并放到緩存中,這樣再出現(xiàn)查詢這個key 的請求的時候,直接返回null即可 。
但是還需要注意的就是需要有一個失效時間,因為如果不設(shè)置失效的話,如果哪天總部有貨了,門店還是當(dāng)做沒貨的話,就會影響銷量了。
BloomFilter
很多時候,緩存穿透是因為有很多惡意流量的請求,這些請求可能隨機生成很多Key來請求查詢,這些肯定在緩存和數(shù)據(jù)庫中都沒有,那就很容易導(dǎo)致緩存穿透。
針對類似的情況,可以使用一個過濾器。
比如如果有一群人經(jīng)常來門店問一些根本不存在的色號,比如五彩斑斕的黑,這些色號該品牌根本沒生產(chǎn)過的話,店員就可以直接告訴顧客不存在就行了,也不需要驚動總部。
在緩存穿透防治上常用的技術(shù)是布隆過濾器(Bloom Filter)。
布隆過濾器是一種比較巧妙的概率性數(shù)據(jù)結(jié)構(gòu),它可以告訴你數(shù)據(jù)一定不存在或可能存在,相比Map、Set、List等傳統(tǒng)數(shù)據(jù)結(jié)構(gòu)它占用內(nèi)存少、結(jié)構(gòu)更高效。
對于緩存穿透,我們可以將查詢的數(shù)據(jù)條件都哈希到一個足夠大的布隆過濾器中,用戶發(fā)送的請求會先被布隆過濾器攔截,一定不存在的數(shù)據(jù)就直接攔截返回了,從而避免下一步對數(shù)據(jù)庫的壓力。
緩存擊穿
有一種比較特殊的情況,那就是如果某一個熱門色號的口紅剛好賣完了,這時候有很多顧客同時來咨詢要購買這個色號,那么門店內(nèi)的多個售貨員可能分別給總部打電話咨詢是否有存貨。
或者如果有多家門店同時賣完了,那么總部接收到的咨詢量就會劇增。類似這種情況,在緩存領(lǐng)域有一個類似的概念叫做緩存擊穿。
緩存擊穿是指當(dāng)某一key的緩存過期時大并發(fā)量的請求同時訪問此key,瞬間擊穿緩存服務(wù)器直接訪問數(shù)據(jù)庫,讓數(shù)據(jù)庫處于負(fù)載的情況。
異步定時更新
如果提前知道某一個色號比較暢銷的話,那就可以定時的咨詢總部是否還有存貨,定時的更新庫存情況就可以避免上面這種情況了。
在緩存處理上,同理,比如某一個熱點數(shù)據(jù)的過期時間是1小時,那么每59分鐘,通過定時任務(wù)去更新這個熱點key,并重新設(shè)置其過期時間。
互斥鎖
還有一種解決辦法,那就是如果很多顧客咨詢的是同一個色號的口紅,那么就先處理第一個用戶的咨詢,其他同樣請求的顧客先排隊等待。一直到店員從總部那里獲取到最新的庫存信息后,就可以安排其他人繼續(xù)購買了。
在緩存處理上,通常使用一個互斥鎖來解決緩存擊穿的問題。簡單來說就是當(dāng)Redis中根據(jù)key獲得的value值為空時,先鎖上,然后從數(shù)據(jù)庫加載,加載完畢,釋放鎖。若其他線程也在請求該key時,發(fā)現(xiàn)獲取鎖失敗,則先阻塞。
緩存雪崩
如果門店內(nèi)的多個色號的口紅同時售罄了,并且門店在這個時間點剛好也不知道總部有沒有庫存了,這時候如果有大量顧客來到門店購物的話,就會有更多的咨詢電話打到總部那里。
或者是門店突然出現(xiàn)問題了,不能提供服務(wù)了,很多顧客就可能自己打電話到總部咨詢庫存情況。類似這種情況,在緩存領(lǐng)域有一個類似的概念叫做緩存雪崩。
緩存雪崩是指當(dāng)大量緩存同時過期或緩存服務(wù)宕機,所有請求的都直接訪問數(shù)據(jù)庫,造成數(shù)據(jù)庫高負(fù)載,影響性能,甚至數(shù)據(jù)庫宕機。
不同的過期時間
為了避免緩存雪崩,門店可以考慮給不同的色號的口紅預(yù)留不同的庫存,并且采用不同的頻率咨詢總部庫存情況,更新到門店中。這樣就可以避免突然同一個時間點所有色號都售罄。
為了避免大量的緩存在同一時間過期,可以把不同的key過期時間設(shè)置成不同的, 并且通過定時刷新的方式更新過期時間。
集群
為了避免門店出問題導(dǎo)致大量顧客直接打電話到總部,可以考慮開更多的門店,將用戶分流到多個店鋪中。
類似的,在緩存雪崩問題防治上面,一個比較典型的技術(shù)就是采用集群方式部署,使用集群可以避免服務(wù)單點故障。
關(guān)于作者:漫話編程,是一個通過漫畫+音頻的形式講解枯燥的編程知識的公眾號。致力于讓編程變得更有樂趣。
本文轉(zhuǎn)載自微信公眾號「漫話編程」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系漫話編程公眾號。