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

一般來講,在咱們的系統中會把數據永久保存在DB中,而且冗餘一份數據在緩存中。讀請求優先從緩存讀取數據,沒有再從DB讀取,以下圖:緩存

這樣作的好處是能夠減少DB的壓力,提升請求的響應速度。架構

但這種架構在提高系統讀請求處理能力的同時,給系統寫請求的處理帶來了很多的麻煩。由於數據在DB跟緩存中各自保存了一份,如何保證它們之間的數據一致就是須要注意的問題了。異步

 

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

1、先寫緩存再寫DB

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

2、先寫DB再寫緩存

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

 

3、問題分析

問題本質上就是一個分佈式數據一致性問題,在不要求強一致性的場景下,咱們只要開闢一個異步任務去保證最終一致性便可。線程

就上面所說的場景來講,發生失敗時,咱們能夠開啓一個異步線程去作數據回填操做,反覆重試直到成功。若是採用異步線程回填數據的方式作最終一致性,那麼這個容錯性是內存級別的,也就是說若是此時重啓服務(線程消失),那麼這個重試任務就丟失了,致使數據不一致。blog

其實宏觀上來講,緩存數據設置過時時間就是一種數據最終一致性的方案。這種方案下,咱們能夠對存入緩存的數據設置過時時間,全部的寫操做以DB爲準,對緩存操做只是盡最大努力便可。也就是說若是DB寫成功,緩存更新失敗,那麼只要到達過時時間,則後面的讀請求天然會從DB中讀取新值而後回填緩存,完成數據的最終一致性。
相關文章
相關標籤/搜索