談談 緩存和數據庫一致性的問題


通常來說,在我們的系統中會把數據永久保存在DB中,並且冗余一份數據在緩存中。讀請求優先從緩存讀取數據,沒有再從DB讀取,如下圖:

這樣做的好處是可以減小DB的壓力,提高請求的響應速度。

但這種架構在提升系統讀請求處理能力的同時,給系統寫請求的處理帶來了不少的麻煩。因為數據在DB跟緩存中各自保存了一份,如何保證它們之間的數據一致就是需要注意的問題了。

 

當處理寫請求時有兩種方式:

一、先寫緩存再寫DB

  1. 如果第一步寫緩存失敗,直接返回,無影響。
  2. 如果緩存寫成功,DB寫失敗,此時如果不清除緩存中已寫入的數據,則會造成數據不一致(緩存中是新值,DB中是舊值)。
    如果增加清除緩存的邏輯,那么清除操作又失敗了該如何處理?

二、先寫DB再寫緩存

  1. 如果DB寫入失敗,直接返回,無影響。
  2. 如果DB寫入成功,緩存寫入失敗則會造成數據不一致(即DB中是新值,緩存中是舊值)。
    如果重試寫入緩存,那重試也失敗該如何處理?

 

三、問題分析

問題本質上就是一個分布式數據一致性問題,在不要求強一致性的場景下,我們只要開辟一個異步任務去保證最終一致性即可。

就上面所說的場景來說,發生失敗時,我們可以開啟一個異步線程去做數據回填操作,反復重試直到成功。如果采用異步線程回填數據的方式做最終一致性,那么這個容錯性是內存級別的,也就是說如果此時重啟服務(線程消失),那么這個重試任務就丟失了,導致數據不一致。

其實宏觀上來說,緩存數據設置過期時間就是一種數據最終一致性的方案。這種方案下,我們可以對存入緩存的數據設置過期時間,所有的寫操作以DB為准,對緩存操作只是盡最大努力即可。也就是說如果DB寫成功,緩存更新失敗,那么只要到達過期時間,則后面的讀請求自然會從DB中讀取新值然后回填緩存,完成數據的最終一致性。
 
 
 

 


免責聲明!

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



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