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