Redis緩存三大異常的處理方案梳理總結(jié)
Redis作為一個高性能的內(nèi)存中的key-value數(shù)據(jù)結(jié)構(gòu)存儲系統(tǒng),在我們?nèi)粘i_發(fā)中廣泛應(yīng)用于緩存、計數(shù)器、消息隊列、排行榜等場景中,尤其是作為最常用的緩存方式,在提高數(shù)據(jù)查詢效率、保護(hù)數(shù)據(jù)庫等方面起到了不可磨滅的作用,但實際應(yīng)用中,可能會出現(xiàn)一些Redis緩存異常的情況,本文主要對Redis緩存異常及處理方案進(jìn)行了總結(jié)。
一、背景
Redis是一個完全開源的、遵守BSD協(xié)議的、高性能的key-value數(shù)據(jù)結(jié)構(gòu)存儲系統(tǒng),它支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保存在磁盤中,而且不僅僅支持簡單的key-value類型的數(shù)據(jù),同時還提供list,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲,功能十分強(qiáng)大,Redis還支持?jǐn)?shù)據(jù)的備份,即master-slave模式的數(shù)據(jù)備份,從而提高可用性。當(dāng)然最重要的還是讀寫速度快,作為我們平常開發(fā)中最常用的緩存方案被廣泛應(yīng)用。但在實際應(yīng)用過程中,它會存在緩存雪崩、緩存擊穿和緩存穿透等異常情況,如果忽視這些情況可能會帶來災(zāi)難性的后果,下面主要對這些緩存異常和常見處理方案進(jìn)行相應(yīng)分析與總結(jié)。
二、緩存雪崩
(一)是什么
一段時間內(nèi)本應(yīng)在redis緩存中處理的大量請求,都發(fā)送到了數(shù)據(jù)庫進(jìn)行處理,導(dǎo)致對數(shù)據(jù)庫的壓力迅速增大,嚴(yán)重時甚至可能導(dǎo)致數(shù)據(jù)庫崩潰,從而導(dǎo)致整個系統(tǒng)崩潰,就像雪崩一樣,引發(fā)連鎖效應(yīng),所以叫緩存雪崩。
(二)為什么
出現(xiàn)上述情況的常見原因主要有以下兩點:
- 大量緩存數(shù)據(jù)同時過期,導(dǎo)致本應(yīng)請求到緩存的需重新從數(shù)據(jù)庫中獲取數(shù)據(jù)。
- redis本身出現(xiàn)故障,無法處理請求,那自然會再請求到數(shù)據(jù)庫那里。
(三)怎么辦
針對大量緩存數(shù)據(jù)同時過期的情況:
- 實際設(shè)置過期時間時,應(yīng)當(dāng)盡量避免大量key同時過期的場景,如果真的有,那就通過隨機(jī)、微調(diào)、均勻設(shè)置等方式設(shè)置過期時間,從而避免同一時間過期。
- 添加互斥鎖,使得構(gòu)建緩存的操作不會在同一時間進(jìn)行。
- 雙key策略,主key是原始緩存,備key為拷貝緩存,主key失效時,可以訪問備key,主key緩存失效時間設(shè)置為短期,備key設(shè)置為長期。
- 后臺更新緩存策略,采用定時任務(wù)或者消息隊列的方式進(jìn)行redis緩存更新或移除等。
針對redis本身出現(xiàn)故障的情況:
- 在預(yù)防層面,可以通過主從節(jié)點的方式構(gòu)建高可用的集群,也就是實現(xiàn)主Redis實例掛掉后,能有其他從庫快速切換為主庫,繼續(xù)提供服務(wù)。
- 如果事情已經(jīng)發(fā)生了,那就要為了防止數(shù)據(jù)庫被大量的請求搞崩潰,可以采用服務(wù)熔斷或者請求限流的方法。當(dāng)然服務(wù)熔斷相對粗暴一些,停止服務(wù)直到redis服務(wù)恢復(fù),請求限流相對溫和一些,保證一些請求可以處理,不是一刀切,不過還是看具體業(yè)務(wù)情況選擇合適的處理方案。
三、緩存擊穿
(一)是什么
緩存擊穿一般出現(xiàn)在高并發(fā)系統(tǒng)中,是大量并發(fā)用戶同時請求到緩存中沒有但數(shù)據(jù)庫中有的數(shù)據(jù),也就是同時讀緩存沒讀到數(shù)據(jù),又同時去數(shù)據(jù)庫去取數(shù)據(jù),引起數(shù)據(jù)庫壓力瞬間增大。和緩存雪崩不同的是,緩存擊穿指并發(fā)查同一條數(shù)據(jù),緩存雪崩是不同數(shù)據(jù)都過期了,很多數(shù)據(jù)都查不到從而查數(shù)據(jù)庫。
(二)為什么
這種情況其實一般出現(xiàn)的原因就是某個熱點數(shù)據(jù)緩存過期,由于是熱點數(shù)據(jù),請求并發(fā)量又大,所以過期的時候還是會有大量請求同時過來,來不及更新緩存就全部打到數(shù)據(jù)庫那邊了。
(三)怎么辦
針對這種情況有兩種常見的處理方案:
- 簡單粗暴的對熱點數(shù)據(jù)不設(shè)置過期時間,這樣不會過期,自然也就不會出現(xiàn)上述情況了,如果后續(xù)想清理,可以通過后臺進(jìn)行清理。
- 添加互斥鎖,即當(dāng)過期之后,除了請求過來的第一個查詢的請求可以獲取到鎖請求到數(shù)據(jù)庫,并再次更新到緩存中,其他的會被阻塞住,直到鎖被釋放,同時新的緩存也被更新上去了,后續(xù)請求又會請求到緩存上,這樣就不會出現(xiàn)緩存擊穿了。
四、緩存穿透
(一)是什么
緩存穿透是指數(shù)據(jù)既不在redis中,也不在數(shù)據(jù)庫中,這樣就導(dǎo)致每次請求過來的時候,在緩存中找不到對應(yīng)key之后,每次都還要去數(shù)據(jù)庫再查詢一遍,發(fā)現(xiàn)數(shù)據(jù)庫也沒有,相當(dāng)于進(jìn)行了兩次無用的查詢。這樣請求就可以繞過緩存直接查數(shù)據(jù)庫,如果這個時候有人想惡意攻擊系統(tǒng),就可以故意使用空值或者其他不存在的值進(jìn)行頻繁請求,那么就會對數(shù)據(jù)庫造成比較大的壓力。
(二)為什么
這種現(xiàn)象的原因其實很好理解,業(yè)務(wù)邏輯里面如果用戶對某些信息還沒有進(jìn)行相應(yīng)的操作或者處理,那對應(yīng)的存放信息的數(shù)據(jù)庫或者緩存中自然也就沒有相應(yīng)的數(shù)據(jù),也就容易出現(xiàn)上述問題。
(三)怎么辦
針對緩存穿透,一般有以下三種處理方案:
- 非法請求的限制,主要是指參數(shù)校驗、鑒權(quán)校驗等,從而一開始就把大量的非法請求攔截在外,這在實際業(yè)務(wù)開發(fā)中是必要的手段。
- 緩存空值或者默認(rèn)值,如果從緩存取不到的數(shù)據(jù),在數(shù)據(jù)庫中也沒有取到,那我們?nèi)匀话堰@個空結(jié)果進(jìn)行緩存,同時設(shè)置一個較短的過期時間。通過這個設(shè)置的默認(rèn)值存放到緩存,這樣第二次到緩存中獲取就有值了,而不會繼續(xù)訪問數(shù)據(jù)庫,可以防止有大量惡意請求是反復(fù)用同一個key進(jìn)行攻擊。
- 使用布隆過濾器快速判斷數(shù)據(jù)是否存在。那什么是布隆過濾器呢,簡單來說,就是可以引入了多個相互獨立的哈希函數(shù),保證在給定的空間和誤判率下,完成元素判重。因為我們知道,存在hash碰撞這樣一種情況,那如果只使用一個hash函數(shù),則碰撞沖突的概率明顯會變大,那為了減少這種沖突,我們可以多引入幾個hash函數(shù),而布隆過濾器算法的核心思想就是利用多個不同的hash函數(shù)來解決這樣一種沖突。它的優(yōu)點是空間效率高,查詢時間短,遠(yuǎn)超其他算法,而它的缺點就是會存在一定的誤識別率,它不能完全保證請求過來的key,通過布隆過濾器的校驗,就一定有這個數(shù)據(jù),畢竟理論上還是會存在沖突情況,無論概率多小。但是,只要沒有通過布隆過濾器的校驗,那么這個key就一定不存在,只要利用這一點其實就已經(jīng)可以過濾掉大部分不存在的key的請求了,在正常場景下已然足夠了。
五、其他
除了上述三種常見的Redis緩存異常問題之外,還經(jīng)常聽到的有緩存預(yù)熱和緩存降級兩個名詞,與其說是異常問題,不如說是兩種的優(yōu)化處理方法。
(一)緩存預(yù)熱
緩存預(yù)熱就是系統(tǒng)上線前后,將相關(guān)的緩存數(shù)據(jù)直接加載到緩存系統(tǒng)中去,而不依賴用戶。這樣就可以避免在用戶請求的時候,先查詢數(shù)據(jù)庫,然后再將數(shù)據(jù)緩存的問題。用戶直接查詢事先被預(yù)熱的緩存數(shù)據(jù),這樣可以避免那么系統(tǒng)上線初期,對于高并發(fā)的流量,都會訪問到數(shù)據(jù)庫中, 對數(shù)據(jù)庫造成流量的壓力。
根據(jù)數(shù)據(jù)不同量級,可以有以下幾種做法:
- 數(shù)據(jù)量不大:項目啟動的時候自動進(jìn)行加載。
- 數(shù)據(jù)量較大:后臺定時刷新緩存。
- 數(shù)據(jù)量極大:只針對熱點數(shù)據(jù)進(jìn)行預(yù)加載緩存操作。
(二)緩存降級
緩存降級是指當(dāng)緩存失效或緩存服務(wù)出現(xiàn)問題時,為了防止緩存服務(wù)故障,導(dǎo)致數(shù)據(jù)庫跟著一起發(fā)生雪崩問題,所以也不去訪問數(shù)據(jù)庫,但因為一些原因,仍然想要保證服務(wù)還是基本可用的,雖然肯定會是有損服務(wù)。因此,對于不重要的緩存數(shù)據(jù),我們可以采取服務(wù)降級策略。
一般做法有以下兩種:
- 直接訪問內(nèi)存部分的數(shù)據(jù)緩存。
- 直接返回系統(tǒng)設(shè)置的默認(rèn)值。
六、總結(jié)
本文主要對常見的Redis緩存異常及其處理方案進(jìn)行了總結(jié),可以用下圖做個概括:
到此這篇關(guān)于Redis緩存三大異常的處理方案梳理總結(jié)的文章就介紹到這了,更多相關(guān)Redis緩存異常內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。