前言
Redis?作為一門熱門的緩存技術(shù),引入了緩存層,就會有緩存異常的三個問題,分別是緩存擊穿、緩存穿透、緩存雪崩。我們用本篇文章來講解下如何解決!
緩存擊穿
緩存擊穿: 指的是緩存中的某個熱點數(shù)據(jù)過期了,但是此時大量的并發(fā)請求訪問這個key的值,此時因為緩存過期無法從緩存中獲取,直接訪問數(shù)據(jù)庫,數(shù)據(jù)庫很容易就會被這些高并發(fā)的請求沖垮,這就是緩存擊穿。
解決方案
- 熱點數(shù)據(jù)不要設(shè)置過期時間,或者在熱點數(shù)據(jù)即將要過期前,提前通過后臺線程更新緩存以及重新設(shè)置過期時間;
- 互斥鎖方案,如果該key的數(shù)據(jù)更新了,那么就通過互斥鎖的方式將其更新。
緩存穿透
緩存穿透:假如用戶訪問的數(shù)據(jù),既不在緩存中,也不在數(shù)據(jù)庫。于是請求在訪問緩存時,發(fā)現(xiàn)緩存沒有命中,繼續(xù)訪問數(shù)據(jù)庫,發(fā)現(xiàn)數(shù)據(jù)庫中也沒有對應(yīng)的key值。當(dāng)有大量這樣的并發(fā)請求到來時,數(shù)據(jù)庫的壓力激增,這就是緩存穿透。
?如上圖紅框所示,一般緩存穿透是遭遇了惡意請求,或者業(yè)務(wù)誤刪緩存跟數(shù)據(jù)庫,導(dǎo)致緩存和數(shù)據(jù)庫中都沒有數(shù)據(jù)。
應(yīng)對緩存穿透,一般是下面兩種方案。
1. 緩存空值或者默認(rèn)值
出現(xiàn)緩存穿透的現(xiàn)象時,我們可以針對查詢的數(shù)據(jù),在緩存中設(shè)置一個空值或者默認(rèn)值,這樣后續(xù)請求就可以從緩存中讀取到空值或者默認(rèn)值,從而不會繼續(xù)查詢數(shù)據(jù)庫。
?2. 使用布隆過濾器(推薦)
布隆過濾器是一種數(shù)據(jù)結(jié)構(gòu),更準(zhǔn)確的說是一種概率型的數(shù)據(jù)結(jié)構(gòu),因為它能判斷某個元素一定不存在或者是可能存在。
在寫入數(shù)據(jù)庫數(shù)據(jù)時,使用布隆過濾器做個標(biāo)記,然后在用戶請求到來時,業(yè)務(wù)線程確認(rèn)緩存失效后,可以通過查詢布隆過濾器快速判斷數(shù)據(jù)是否存在,如果不存在,就不用通過查詢數(shù)據(jù)庫來判斷數(shù)據(jù)是否存在。
緩存雪崩
通常為了保證緩存中的數(shù)據(jù)與數(shù)據(jù)庫中的數(shù)據(jù)一致性,我們會給 Redis 里的數(shù)據(jù)設(shè)置過期時間,當(dāng)緩存數(shù)據(jù)過期后,用戶訪問的數(shù)據(jù)無法命中緩存,業(yè)務(wù)系統(tǒng)需要重新生成緩存,因此就會訪問數(shù)據(jù)庫,并將數(shù)據(jù)更新到 Redis 里。
緩存雪崩: 就是指在大量的應(yīng)用請求無法在 Redis 緩存中進行處理,然后應(yīng)用將大量請求發(fā)送到數(shù)據(jù)庫層,導(dǎo)致數(shù)據(jù)庫層的壓力驟增。
一般是以下兩種情況導(dǎo)致的:
緩存中的大量數(shù)據(jù)在同一時間過期,導(dǎo)致大量請求無法得到處理。
Redis 緩存實例發(fā)生故障宕機了,無法處理請求,導(dǎo)致大量請求一下子積壓到數(shù)據(jù)庫層面
大量數(shù)據(jù)同時過期
解決方案
過期時間添加隨機數(shù)
首先,我們要避免給大量的數(shù)據(jù)設(shè)置相同的過期時間。如果業(yè)務(wù)真的有這個需求,我們可以在用 EXPIRE 命令給每個數(shù)據(jù)設(shè)置過期時間時,給這些數(shù)據(jù)的過期時間增加一個較小的隨機數(shù),既能避免了大量數(shù)據(jù)同時過期,又保證了這些數(shù)據(jù)基本在相近的時間失效,依然能滿足業(yè)務(wù)需求。
互斥鎖
當(dāng)業(yè)務(wù)線程在處理用戶請求時,如果發(fā)現(xiàn)訪問的數(shù)據(jù)不在 Redis 里,就加個互斥鎖,保證同一時間內(nèi)只有一個請求來構(gòu)建緩存,當(dāng)緩存構(gòu)建完畢后,再釋放鎖。未能獲取互斥鎖的請求,要么等待鎖釋放后重新讀取緩存,要么就返回空值或者默認(rèn)值。
Redis 故障宕機
解決方案:
- 服務(wù)熔斷或請求限流
發(fā)生緩存雪崩時,為了防止引發(fā)連鎖的數(shù)據(jù)庫雪崩,甚至是整個系統(tǒng)的崩潰,我們暫停業(yè)務(wù)應(yīng)用對緩存系統(tǒng)的接口訪問。具體點說,就是業(yè)務(wù)應(yīng)用調(diào)用緩存接口時,緩存客戶端并不把請求發(fā)給 Redis 緩存實例,而是直接返回,等到 Redis 緩存實例重新恢復(fù)服務(wù)后,再允許應(yīng)用請求發(fā)送到緩存系統(tǒng)。
為了減少對業(yè)務(wù)的影響,我們可以啟用請求限流機制,只將少部分請求發(fā)送到數(shù)據(jù)庫進行處理,再多的請求就在入口直接拒絕服務(wù),等到 Redis 恢復(fù)正常并把緩存預(yù)熱完后,再解除請求限流的機制。文章來源:http://www.zghlxwxcb.cn/news/detail-632290.html
- 構(gòu)建 Redis 緩存高可靠集群
如果 Redis 緩存的主節(jié)點故障宕機了,從節(jié)點可以切換成為主節(jié)點,繼續(xù)提供緩存服務(wù),避免了由于緩存實例宕機而導(dǎo)致的緩存雪崩問題。文章來源地址http://www.zghlxwxcb.cn/news/detail-632290.html
?
到了這里,關(guān)于Redis 如何解決緩存雪崩、緩存擊穿、緩存穿透難題的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!