天天看點

資料庫主從不一緻,怎麼解?

在聊資料庫與緩存一緻性問題之前,先聊聊資料庫主庫與從庫的一緻性問題。

問:常見的資料庫叢集架構如何?

答:一主多從,主從同步,讀寫分離。

資料庫主從不一緻,怎麼解?

如上圖:

(1)一個主庫提供寫服務

(2)多個從庫提供讀服務,可以增加從庫提升讀性能

(3)主從之間同步資料

畫外音:任何方案不要忘了本心,加從庫的本心,是提升讀性能。

問:為什麼會出現不一緻?

答:主從同步有時延,這個時延期間讀從庫,可能讀到不一緻的資料。

資料庫主從不一緻,怎麼解?

(1)服務發起了一個寫請求

(2)服務又發起了一個讀請求,此時同步未完成,讀到一個不一緻的髒資料

(3)資料庫主從同步最後才完成

畫外音:任何資料備援,必将引發一緻性問題。

問:如何避免這種主從延時導緻的不一緻?

答:常見的方法有這麼幾種。

方案一:忽略

任何脫離業務的架構設計都是耍流氓,絕大部分業務,例如:百度搜尋,淘寶訂單,QQ消息,58文章都允許短時間不一緻。

畫外音:如果業務能接受,最推崇此法。

如果業務能夠接受,别把系統架構搞得太複雜。

方案二:強制讀主

資料庫主從不一緻,怎麼解?

(1)使用一個高可用主庫提供資料庫服務

(2)讀和寫都落到主庫上

(3)采用緩存來提升系統讀性能

這是很常見的微服務架構,可以避免資料庫主從一緻性問題。

方案三:選擇性讀主

強制讀主過于粗暴,畢竟隻有少量寫請求,很短時間,可能讀取到髒資料。

有沒有可能實作,隻有這一段時間,可能讀到從庫髒資料的讀請求讀主,平時讀從呢?

可以利用一個緩存記錄必須讀主的資料。

資料庫主從不一緻,怎麼解?

如上圖,當寫請求發生時:

(1)寫主庫

(2)将哪個庫,哪個表,哪個主鍵三個資訊拼裝一個key設定到cache裡,這條記錄的逾時時間,設定為“主從同步時延”

畫外音:key的格式為“db:table:PK”,假設主從延時為1s,這個key的cache逾時時間也為1s。

資料庫主從不一緻,怎麼解?

如上圖,當讀請求發生時:

這是要讀哪個庫,哪個表,哪個主鍵的資料呢,也将這三個資訊拼裝一個key,到cache裡去查詢,如果,

(1)cache裡有這個key,說明1s内剛發生過寫請求,資料庫主從同步可能還沒有完成,此時就應該去主庫查詢

(2)cache裡沒有這個key,說明最近沒有發生過寫請求,此時就可以去從庫查詢

以此,保證讀到的一定不是不一緻的髒資料。

總結

資料庫主庫和從庫不一緻,常見有這麼幾種優化方案:

(1)業務可以接受,系統不優化

(2)強制讀主,高可用主庫,用緩存提高讀性能

(3)在cache裡記錄哪些記錄發生過寫請求,來路由讀主還是讀從

文字很短,不能解決所有問題,但希望能給大家一些啟示。

有更好的方案,歡迎交流。

資料庫主從不一緻,怎麼解?