Redis 的緩存異常處理 —— 緩存雪崩、緩存擊穿、緩存穿透
在實(shí)際應(yīng)用 Redis 過程中,如果將 Redis 作為數(shù)據(jù)庫的緩存,經(jīng)常會遇到這幾個(gè)問題:緩存雪崩、緩存擊穿、緩存穿透等。
緩存雪崩
緩存雪崩指的是,大量的應(yīng)用無法在 Redis 緩存中處理,然后大量請求發(fā)送到了數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫的壓力激增,甚至可能導(dǎo)致數(shù)據(jù)庫崩潰,從而導(dǎo)致整個(gè)系統(tǒng)崩潰,引發(fā)雪崩一樣的連鎖效應(yīng)。
而引起緩存雪崩的原因,一般如下:
1、緩存中大量 key 同時(shí)過期
2、Redis 實(shí)例掛掉了,無法處理請求
對于原因 1,在實(shí)際應(yīng)用中應(yīng)當(dāng)避免大量 key 同時(shí)過期的場景。如果確實(shí)有這種業(yè)務(wù)場景,可以微調(diào)這批 key 過期的時(shí)間,使其能有一定的相差間隔。
對于原因2,之前提到的Redis 主從集群其實(shí)可以比較好地實(shí)現(xiàn)主 Redis 實(shí)例掛掉后,能有其他從庫快速切換為主庫,繼續(xù)提供服務(wù)。
當(dāng)然,以上都是預(yù)防的措施,如果已經(jīng)發(fā)生了 緩存雪崩,為了防止數(shù)據(jù)庫被大量的請求搞崩潰,可以采用 服務(wù)熔斷 或者 請求限流。
服務(wù)熔斷就是暫停對業(yè)務(wù)提供 Redis 服務(wù),直到 Redis 恢復(fù)正常,再向外提供服務(wù)。當(dāng)然,這種情況下,業(yè)務(wù)也會整個(gè)停擺了。另外一種比較溫和的辦法就是請求限流。請求限流顧名思義,就是限制請求的流量,隨機(jī)丟棄一部分的請求,以保證不會同時(shí)有太多請求壓入數(shù)據(jù)庫。
緩存擊穿
緩存擊穿是指,針對某個(gè)熱點(diǎn)數(shù)據(jù),突然在緩存中失效,然后這些請求到熱點(diǎn)數(shù)據(jù)的請求會都請求到數(shù)據(jù)庫。
緩存擊穿一般是熱點(diǎn) key 在 Redis 中過期了導(dǎo)致的。最直接的方法就是,對于熱點(diǎn) key ,就不設(shè)置過期時(shí)間。
緩存穿透
緩存穿透指的是,數(shù)據(jù)既不在 Redis 中,也不在數(shù)據(jù)庫中。每次請求 Redis 發(fā)現(xiàn)沒有對應(yīng)的 key之后,再去請求數(shù)據(jù)庫,發(fā)現(xiàn)數(shù)據(jù)庫也沒有。那么這時(shí), Redis 就相當(dāng)于一個(gè)擺設(shè),沒有具體的作用了。如果有人惡意攻擊系統(tǒng),故意使用空值或者其他不存在的值進(jìn)行頻繁請求,那么也會對數(shù)據(jù)庫造成比較大的壓力。
為了避免緩存穿透,我們可以:
1、緩存空值或缺省值
2、采用布隆過濾器,提前判斷是否有此數(shù)據(jù)。
布隆過濾器實(shí)際上就是把 key 通過三次不同的哈希,計(jì)算出三個(gè)哈希值,然后在哈希表中把對應(yīng)哈希值位置置為1。當(dāng)有新的請求過來時(shí),先判斷這個(gè) key 經(jīng)過N次哈希后,對應(yīng)的哈希值位置是否為1,只要有一個(gè)不為1,就說明此 key 之前沒有緩存過。
實(shí)際上,布隆過濾器也是有缺陷的,它不能完全保證請求過來的 key ,通過布隆過濾器的校驗(yàn),就一定有這個(gè)數(shù)據(jù)。但是,只要沒有通過布隆過濾器的校驗(yàn),那么這個(gè) key 就一定不存在。其實(shí)這樣就已經(jīng)可以過濾掉大部分不存在的 key 請求了。
正如以上提到的布隆過濾器缺陷,如果布隆過濾器的哈希槽過短,很有可能導(dǎo)致大部分的位置都為 1 ,那么此時(shí),布隆過濾器就失去了它的意義。所以,當(dāng)我們發(fā)現(xiàn)布隆過濾器大部分位置都為1了,應(yīng)該要擴(kuò)寬哈希槽。
3、在實(shí)際業(yè)務(wù)中,我們對于請求的參數(shù)應(yīng)該要先進(jìn)行校驗(yàn),請求的參數(shù)應(yīng)該要在規(guī)定范圍內(nèi)。實(shí)際上,在工程應(yīng)用中,主要也是依賴于參數(shù)的校驗(yàn),過濾掉很多無效請求。
數(shù)據(jù)不一致性
當(dāng)使用 Redis 作為數(shù)據(jù)庫緩存時(shí),可能會存在數(shù)據(jù)不一致的問題。
當(dāng)需要修改一份數(shù)據(jù)時(shí),需要同時(shí)修改數(shù)據(jù)庫和緩存,那么這里就要區(qū)分:先修改數(shù)據(jù)庫還是修改緩存;對于緩存,是直接修改數(shù)據(jù)還是刪除數(shù)據(jù)?

本文轉(zhuǎn)自網(wǎng)絡(luò),由于無法追述來源,如有侵權(quán),聯(lián)系浪尖刪除:langjianliaodashuju
