緩存雪崩、緩存穿透等這些問題除了大廠面試經常問,還有我們實際的工作中也會經常遇到以上的場景,下面我就來詳解Redis緩存雪崩、緩存穿透、緩存并發等5大難題@mikechen
緩存雪崩
緩存雪崩是指在緩存中存儲的一批資料在同一時間段内同時過期失效,而對這批資料的請求全部轉發到了資料庫中,導緻資料庫短時間内承受大量的請求而崩潰。
如下圖所示:
比如:如果redis叢集大面積故障,這個時候緩存失效,Redis大量失效後,大量請求轉向到mysql資料庫。
mysql的調用量暴增,很快就扛不住了,甚至直接當機,這個就是典型的緩存雪崩。
其主要原因是因為緩存系統中某些不可控因素導緻大量緩存資料同時失效,而業務請求量并沒有減少。
02 緩存雪崩解決方案
緩存雪崩的解決方法:
1.提前預熱緩存
即在緩存過期之前,提前去更新緩存資料,確定緩存資料不會在同一時間段内全部失效。
2.設定不同的緩存失效時間
設定不同的緩存失效時間,防止在同一時間失效。
3.緩存的高可用性
緩存層設計成高可用,防止緩存大面積故障,即使個别節點、甚至是機房宕掉,依然可以提供服務。
例如:提供Redis Sentinel 和 Redis Cluster等方案,都實作Redis的高可用。
可用性增強,可以減低緩存雪崩的風險。
4.緩存降級
當通路量劇增、服務出現問題仍然需要保證服務還是可用的。系統可以根據一些關鍵資料進行自動降級,也可以配置開關實作人工降級,這裡會涉及到運維的配合。
降級的最終目的是保證核心服務可用,即使是有損的。
比如:我的淘寶頁面,由于是非核心頁面,後端服務如果暫時不能提供使用的情況。
可以考慮直接使用一個靜态頁面替換掉,這樣對于使用者也是永遠提供服務的狀态,也不至于出現空白或者異常錯誤的裸奔狀态。
5.提前演練
最後,建議還是在項目上線前,演練緩存層宕掉後,應用以及後端的負載情況以及可能出現的問題,對高可用提前預演,提前發現問題。
緩存穿透
緩存穿透是指查詢一個一定不存在的資料,由于緩存中沒有這個資料,每次查詢都會穿過緩存,請求直接到達資料庫。
如果這種不存在的資料請求量過大,就會導緻資料庫壓力過大甚至崩潰。
緩存穿透的主要原因是因為惡意攻擊或者程式錯誤導緻的緩存查詢。
解決思路:
1.布隆過濾器
使用布隆過濾器對請求的key進行過濾,如果不存在則直接傳回,不再進行後續的查詢操作。
2.設定預設值
如果查詢資料庫也為空,直接設定一個預設值存放到緩存。
這樣第二次到緩沖中擷取就有值了,而不會繼續通路資料庫。
3.限流
限制同一個IP或同一個key的請求通路頻率,限制單個請求的通路頻率,避免惡意攻擊。
緩存并發
這裡的并發指的是多個redis的client同時set key引起的并發問題。
比如:利用jedis等用戶端對Redis進行并發通路時會出現問題。
比如:同時有多個子系統去set一個key。
解決方案:
主要是把redis.set操作放在隊列中使其串行化,可以使用redis分布式鎖,必須的一個一個執行。
緩存預熱
緩存預熱是指在系統啟動之後,将部分或者全部熱門資料提前加載到緩存中,以便于使用者第一次請求時可以快速地從緩存中擷取資料,提高系統的性能和響應速度。
這樣就可以避免在使用者請求的時候,先查詢資料庫,然後再将資料緩存的問題,使用者直接查詢事先被預熱的緩存資料。
解決思路:
1、直接寫個緩存重新整理頁面,上線時手工操作下。
2、資料量不大,可以在項目啟動的時候自動進行加載。
以上
更多分布式架構系列、阿裡架構師進階系列,請檢視以下文章:
阿裡架構師進階從0到1全部合集(建議收藏)