解決數據庫和緩存數據不一致情況:延遲雙刪


在高並發的場景下,數據庫處理數據增刪改查很是薄弱。有一些數據查詢的頻率遠大於修改頻率,就需要使用緩存技術,讓先去請求redis,redis存在返回緩存數據,redis不存在就查詢數據庫,返回數據的同時將數據緩存到redis中。

問題

讀取緩存一般沒有什么問題,一旦涉及到數據更新:數據庫或者緩存更新,就容易出現緩存和數據庫數據不一致情況。首先,數據“一致性”包含兩種情況:

  1. 緩存有數據,那么緩存的值和數據庫中的值相同。
  2. 緩存沒有數據,那么,數據庫中的值必須是最新值。

在高並發的情況下,不管是先寫數據庫,再刪緩存;還是先刪緩存,再寫數據庫,都有可能出現數據不一致的情況,比如:

  1. 如果刪除了緩存redis,還沒來得及寫庫mysql,另一個線程就讀取,發現緩存為空,則去數據庫讀取數據寫入緩存,此時緩存中的數據為臟數據。
  2. 如果寫了庫,在刪除緩存前,寫庫的線程宕機了,也會出現數據不一致的情況。

解決辦法

延遲雙刪策略

1、先刪除緩存
2、再寫數據庫
3、休眠500ms(根據統計線程讀取數據和寫緩存的時間)
(休眠的作用是當前線程等其他線程讀完了數據后寫入緩存后,刪除緩存)
4、再刪除緩存

設置緩存過期時間

總結

先清除緩存,然后再寫入數據庫。有可能存在刪除緩存以后,另一個線程讀取數據,發現沒有數據,就去數據讀取數據,然后寫入緩存中,此時緩存中的數據為臟數據;
解決辦法:

  1. 先刪除緩存
  2. 再寫入數據庫
  3. 休眠500ms
  4. 刪除緩存
    其中第三步驟的500ms,是根據業務讀取數據平均耗時,這樣做的目的是確保讀請求可以結束,寫請求可以刪除讀請求造成的臟數據的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM