緩存不一致問題
緩存更新的4種策略
-
1.給緩存設置過期時間。這樣緩存和數據庫能保持最終一致性。
-
2.先更新數據庫,再更新緩存。問題:1.線程A更新了數據庫,線程B再更新了數據庫。線程B更新了緩存,線程A更新了緩存。最終結果是緩存以線程A更新的爲準,數據庫以線程B更新的爲準,出現了不一致。2.更新了數據庫就去更新緩存,實際上可能這些緩存不是熱點數據,且這些緩存需要複雜的計算生成,浪費了性能。3.更新了數據庫,然後更新緩存的時候程序出問題了中止了,那麼也會造成數據不一致問題。
-
3.先刪除緩存,再更新數據庫。問題:同時有一個請求A進行更新操作,另一個請求B進行查詢操作。那麼會出現如下情形:(1)A進行寫操作,刪除緩存(2)B查詢發現緩存不存在(3)B去數據庫查詢得到舊值(4)B將舊值寫入緩存(5)A將新值寫入數據庫。
解決方案:延時雙刪除,僞代碼如下
public void write(String key,Object data){
redis.delKey(key);
db.updateData(data);
// 延時一秒的目的是,讓讀線程B更新完緩存,線程A再去刪除。
Thread.sleep(1000);
redis.delKey(key);
}
- 4.先更新數據庫,再刪除緩存。
假設這會有兩個請求,一個請求A做查詢操作,一個請求B做更新操作,那麼會有如下情形產生
(1)緩存剛好失效
(2)請求A查詢數據庫,得一箇舊值
(3)請求B將新值寫入數據庫
(4)請求B刪除緩存
(5)請求A將查到的舊值寫入緩存
延時刪除可以解決這個問題,即讓讀線程把業務走完再去刪除。
刪除也可能有失敗的情況,需要啓用重試機制。
刪除失敗後,丟入消息隊列,由另外的線程從隊列中獲取去刪除。