DB讀寫分離情況下,如何解決緩存和數據庫不一致性問題?

數據庫 設計 技術 文章 老顧聊技術 2019-05-10

歡迎關注頭條號:老顧聊技術

精品技術文章分享,知識的組裝工


目錄

  1. 前言
  2. 為什麼會導致不一致
  3. 方案一:後臺緩存標記法
  4. 方案二:延遲消息
  5. 方案三:更新用戶再次發起讀請求

前言

你知道如何更新緩存嗎?如何保證緩存和數據庫雙寫一致性? 這篇文章中我們留了一個尾巴,就是在讀寫分離的情況下,緩存和數據庫數據不一致怎麼解決?

推薦大家先去看一下你知道怎麼解決DB讀寫分離,導致數據不一致問題嗎? 這篇文章,如何解決DB數據庫的數據不一致問題。

在緩存和數據庫數據一致性問題中,老顧推薦是的 先更新數據庫,再刪除緩存。如果緩存刪除失敗可以用MQ消息隊列的方式進行重試刪除。

為什麼會導致不一致

DB讀寫分離情況下,如何解決緩存和數據庫不一致性問題?

上圖流程:

1)應用服務(商品服務)請求A更新庫存為99,原值為100

2)但主庫同步到從庫需要時間,還沒有同步完成時,請求B發起讀請求

3)讀請求B走的是從庫,取出來從庫裡面的舊值100

4)讀請求B會把取出來的值,再設置到緩存中,值為100

5)但當從庫同步數據完成,從庫的數據值為99,這就導致數據庫和緩存數據不一致

不知道大家看了DB讀寫分離導致數據不一致的問題這篇文章自己可不可以設計一個方案。老顧建議小夥伴們先自己想一下,如何設計,再往下看。

方案一:後臺緩存標記法

再上篇文章【DB讀寫分離導致數據不一致的問題】裡面提到此方案,這邊就不重複介紹了,大家可以去那篇文章中查看。

數據不一致問題是因為讀請求走的是從庫,把從庫的舊值又設置到緩存中了。後臺緩存標記方案就解決了此問題,在主從數據庫同步窗口時間內,讀請求也是走主庫。這樣就解決了讀請求取到的是舊值這個問題。

但這個方案也有缺點,就是有系統性能問題,降低了吞吐量

方案二:延遲消息

其實在真實業務中,尤其互聯網項目中,數據短時間的不一致時能夠接受的。就像上篇文章【DB讀寫分離導致數據不一致的問題】中提到的本地緩存標記法,保證了本用戶數據一致,其他用戶可暫時不一致,但最終是一致的這個思路。我們可以設置一個延遲消息,如下圖

DB讀寫分離情況下,如何解決緩存和數據庫不一致性問題?

流程:

1)在訂閱到binlog更新日誌時,先不刪除緩存,而是投遞一個延遲消息(如:延遲10秒的消息,就是過10秒此消息才會被消費者監聽到,從而被消費)

2)延遲消息的延遲時間,設置為主庫與從庫的數據同步延遲的時間,可自行預估

3)監聽到延遲消息,在刪除緩存。

這個方案的特點就是讀請求會在延遲時間內讀取到的是舊值,等到延遲時間一過,取到的就是新值。這個業務在互聯網產品中是允許的。

如果要保證本用戶(更新數據的用戶)一定讀到的是新值,這邊可以採用本地緩存標記方案,直接從主數據庫讀取,讀取到數據後,可以把新值設置到緩存中,這樣就保證了數據一致性。

方案三:更新用戶再次發起讀請求

在方案二中,其他用戶的讀請求會有暫時間讀取到的是舊值,如何縮短時間?其實是有一個方案,就是讓更新用戶再次發起讀請求,也就是在方案二最後提到的

1)更新用戶再次發起讀請求,根據本地緩存標記,直接走主數據庫,讀取的肯定是新值,

2)再把這個新值設置到緩存中。這樣就保證了緩存中的是新值,雖然從庫還沒有不同完成,但緩存中已經是新值了。

3)最後從庫同步數據完成,值就達到了一致性

此方案的問題:就是更新操作後,多了一步讀請求。

總結:小夥伴可以根據自己的業務需求,選擇不同的方案,一定要結合自己的業務,沒有什麼完美的方案,只是如何取捨而已。


-End-

如有收穫,請幫忙轉發,您的鼓勵是作者最大的動力,謝謝!

10幾年的經驗實戰分享

相關微服務,分佈式,高併發,高可用,企業實戰,乾貨等原創文章正在路上

歡迎關注頭條號:老顧聊技術

精品技術文章分享,知識的組裝工

推薦閱讀

你知道如何更新緩存嗎?如何保證緩存和數據庫雙寫一致性?

你知道怎麼解決DB讀寫分離,導致數據不一致問題嗎?

你真的知道怎麼使用緩存嗎?

如何利用鎖,防止緩存擊穿?重構思想的重要性

海量訂單產生的業務高峰期,如何避免消息的重複消費?

相關推薦

推薦中...