面試被吊打系列-Redis緩存血崩
本文轉(zhuǎn)載自微信公眾號「JAVA日知錄」,作者單一色調(diào)。轉(zhuǎn)載本文請聯(lián)系JAVA日知錄公眾號。
小張興沖沖去面試,結(jié)果因為redis的緩存雪崩問題被面試官拒絕!
小張:面試官,你好。我是來參加面試的。
面試官:你好,小張。我看了你的簡歷,你們平時在項目中用了redis,能說一下你們使用redis的場景嗎?
小張:redis的話我們主要是用來存儲一些常用的配置類數(shù)據(jù)還有一些熱點數(shù)據(jù);還有存儲一些到期失效的數(shù)據(jù),比如登錄用戶頒發(fā)的token等。
面試官:那好,既然你們用來存儲熱點數(shù)據(jù)。那么我來問你個實際場景,「查詢熱點數(shù)據(jù)的時候會先從緩存加載,如果緩存沒有命中則會檢索數(shù)據(jù)庫獲取數(shù)據(jù)。往往我們還會給熱點緩存數(shù)據(jù)設(shè)置一個過期時間。那么我的問題是,假設(shè)在某一時間點熱點緩存全部過期失效了,這樣所有的請求都會直接進(jìn)入數(shù)據(jù)庫,一瞬間就會把數(shù)據(jù)庫壓垮,如果是你會怎么解決這個問題?」
小張:emm...面試官,我肚子有點不舒服,我先回去了。小張卒!
面試官:因為緩存同一時間大面積的失效,或者緩存服務(wù)暫時不能提供服務(wù)等,從而導(dǎo)致所有請求都去查數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫CPU和內(nèi)存負(fù)載過高,甚至宕機(jī)。這一現(xiàn)象被稱之為 「緩存雪崩」。
緩存血崩可以通過以下四個維度來解決:
「緩存預(yù)熱」
數(shù)據(jù)加熱的含義就是在正式部署之前,先把可能的數(shù)據(jù)先預(yù)先訪問一遍,這樣部分可能大量訪問的數(shù)據(jù)就會加載到緩存中。在即將發(fā)生大并發(fā)訪問前手動觸發(fā)加載緩存不同的key。
「加上互斥鎖」
可以在第一個查詢數(shù)據(jù)的請求上使用一個互斥鎖來鎖住它,其他的線程走到這一步拿不到鎖就等著,等第一個線程查詢到了數(shù)據(jù),然后將數(shù)據(jù)放到redis緩存起來。后面的線程進(jìn)來發(fā)現(xiàn)已經(jīng)有緩存了,就直接走緩存。
「過期時間均勻分布」
給緩存的時效時間加上隨機(jī)因子,即給緩存設(shè)置不同的過期時間,讓緩存失效的時間點盡量均勻。
「構(gòu)建高可用的緩存系統(tǒng)」
把Redis設(shè)計成高可用的,即使個別節(jié)點、個別機(jī)器、甚至是機(jī)房宕掉,依然可以提供服務(wù),例如 Redis Sentinel 和 Redis Cluster 都實現(xiàn)了高可用。
面試官:各位看官朋友們,你們學(xué)會怎么解決緩存雪崩的問題了嗎?希望你們以后面試不會被這個問題難倒喲~
小張:學(xué)到了學(xué)到了,我下次再來。(早知道不提什么熱點數(shù)據(jù)了,不提面試官就不會問。)
面試官:小樣,不問這個那么我不會問其他的了嗎?你下次再來試試!