緩存與數(shù)據(jù)庫一致性問題
對于既有數(shù)據(jù)庫操作又有緩存操作的接口,一般分為兩種執(zhí)行順序。
1、先操作數(shù)據(jù)庫再操作緩存。這種情況下如果數(shù)據(jù)庫操作成功而緩存操作失敗就會導致不一致。
2、先操作緩存再操作數(shù)據(jù)庫,如果緩存操作成功但是數(shù)據(jù)庫操作失敗也會導致不一致的問題。
大部分情況下,緩存理論上都是需要可以從數(shù)據(jù)庫恢復(fù)出來的,所以基本上采取 第一種。
緩存擊穿問題
緩存擊穿指的是惡意用戶頻繁的模擬請求緩存中不存在的數(shù)據(jù),以至于這些請求在短時間內(nèi)直接落到了數(shù)據(jù)庫上,導致數(shù)據(jù)庫性能直接下降,最終影響服務(wù)整體的性能。在實際的項目中很容易遇到,例如搶購活動、秒殺活動的接口API被大量的惡意用戶刷,導致短時間內(nèi)數(shù)據(jù)庫宕機。對于緩存擊穿的問題,如下解決方案。
1、使用互斥鎖排隊。當從緩存中獲取數(shù)據(jù)失敗時,給當前接口加上鎖,從數(shù)據(jù)庫中加載完數(shù)據(jù)并寫入后再釋放鎖。若其他線程獲取鎖失敗則等待一段時間后重試。
2、使用布隆過濾器。將所有可能存在的數(shù)據(jù)緩存放到布隆過濾器中,當黑客訪問不存在的緩存時迅速返回避免緩存以及DB掛掉。
緩存雪崩問題
在短時間內(nèi)有大量緩存失效,如果這期間有大量的請求發(fā)生同樣也有可能導致數(shù)據(jù)庫發(fā)生宕機。在Reids集群的數(shù)據(jù)分布算法上如果使用的是傳統(tǒng)的hash算法在增加或者移除Redis節(jié)點的時候就會出現(xiàn)大量的緩存臨時失效的情形。
1、像解決緩存穿透一樣加鎖排隊。
2、建立備份緩存,緩存A和緩存B,A設(shè)置超時時間,B不設(shè)置超時時間,先從A讀緩存,A沒有讀B,并且更新A緩存和B緩存。
3、計算數(shù)據(jù)緩存節(jié)點的時候采用一致性hash算法,這樣在節(jié)點數(shù)量發(fā)生改變時不會存在大量的緩存數(shù)據(jù)需要遷移的情況發(fā)生。
緩存并發(fā)問題
這里的并發(fā)指的是多個Redis1的客戶端同時set值引起并發(fā)問題。比較有效的解決方案就是把set操作放在隊列中使其串行化,必須得一個一個執(zhí)行。