Redis雪崩、穿透與一致性問題解決方案

1 redis雪崩的解決方案

什麼是緩存雪崩?

(1)Redis掛掉了,請求全部走數據庫。
(2)對緩存數據設置相同的過期時間,導致某段時間內緩存失效,請求全部走數據庫。

1.1 針對redis數據過期失效的策略

在緩存過期的短時間內存在數據庫短暫壓力問題,爲解決該問題,可採用以下兩種解決方案:

第一種:在緩存的時候給過期時間加上一個隨機值,這樣就會大幅度的減少緩存在同一時間過期。
第二種:我們以兩個鍵值對的緩存代替之前的一個,將緩存時間(key-time),和緩存數據(key-data)分離,這樣當緩存過期時,第一個線程發現key-time沒有,則先更新key-time,然後去查詢數據庫(或任何比較耗時的數據查詢方式),並更新key-data的值,當後續線程來獲取數據時,雖然第一個還沒有從數據庫查完並更新緩存,但發現key-time存在,會獲取舊的數據。

雖然按這種方式獲取的數據中c類型的數據爲舊數據,但可以做到:在緩存過期時不至於在短時間內對數據庫造成較高壓力,在數據庫不可用,同時緩存過期的時候,其調用服務皆不可用,造成連鎖反應,而已該解決方式,則可以返回過期數據,爲修復數據庫贏得寶貴時間(緩解雪崩效應)

1.2 針對“Redis掛掉了,請求全部走數據庫”這種情況

我們可以有以下的思路:

事發前:實現redis的高可用,儘量避免redis掛掉這種情況的發生。
事發中:萬一redis真的掛了,可以設置本地緩存+限流,儘量避免數據庫被幹掉,確保服務正常工作。
事發後:redis持久化,重啓後能夠快速恢復緩存數據。

2 緩存穿透的解決方案

什麼是緩存穿透?就是請求的數據在緩存大量不命中,導致請求走數據庫。而緩存穿透如果發生了,也可能把我們的數據庫搞垮,導致整個服務癱瘓!

解決緩存穿透也有兩種方案:

(1)提前進行攔截過濾:由於請求的參數是不合法的(每次都請求不存在的參數),於是我們可以使用布隆過濾器(BloomFilter)或者壓縮filter提前攔截,不合法就不讓這個請求到數據庫層!
(2)設置空對象:當我們從數據庫找不到的時候,我們也將這個空對象設置到緩存裏邊去。下次再請求的時候,就可以從緩存裏邊獲取了。這種情況我們一般會將空對象設置一個較短的過期時間。

3 緩存和數據庫雙寫一致性問題

主要就是兩種策略:第一種:先刪除緩存,再更新數據庫;第二種:先更新數據庫,再刪除緩存。

第一種策略在併發的情況,也會出現不一致的情況,彌補策略,採用延時雙刪策略。如果第二次刪又失敗的話,又考慮性能的話,可採用異步重試的方式進行。
同樣,針對第二種策略,在併發的情況下,也會出現數據不一致的情況,同樣可以採取延遲雙刪的策略。如果第二次刪又失敗的話,又考慮性能的話,可採用異步重試的方式進行。

針對二刪和重試操作,對業務代碼會造成比較多的侵入,針對這種情況,可以啓動一個訂閱程序去訂閱數據庫的binlog,獲得需要操作的數據。在應用程序中,另起一段程序,獲得這個訂閱程序傳來的信息,進行刪除緩存操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章