MySQL冗余數據的三種方案


一,為什么要冗余數據

互聯網數據量很大的業務場景,往往數據庫需要進行水平切分來降低單庫數據量。

 

水平切分會有一個patition key,通過patition key的查詢能夠直接定位到庫,但是非patition key上的查詢可能就需要掃描多個庫了。

 

此時常見的架構設計方案,是使用數據冗余這種反范式設計來滿足分庫后不同維度的查詢需求。

 

例如:訂單業務,對用戶和商家都有訂單查詢需求:

Order(oid, info_detail);

T(buyer_id, seller_id, oid);

如果用buyer_id來分庫,seller_id的查詢就需要掃描多庫。

如果用seller_id來分庫,buyer_id的查詢就需要掃描多庫。

 

此時可以使用數據冗余來分別滿足buyer_id和seller_id上的查詢需求:

T1(buyer_id, seller_id, oid)

T2(seller_id, buyer_id, oid)

同一個數據,冗余兩份,一份以buyer_id來分庫,滿足買家的查詢需求;一份以seller_id來分庫,滿足賣家的查詢需求。

 

如何實施數據的冗余,是今天將要討論的內容。

 

二,服務同步雙寫


顧名思義,由服務層同步寫冗余數據,如上圖1-4流程:

  • 業務方調用服務,新增數據

  • 服務先插入T1數據

  • 服務再插入T2數據

  • 服務返回業務方新增數據成功

 

優點

  • 不復雜,服務層由單次寫,變兩次寫

  • 數據一致性相對較高(因為雙寫成功才返回)

 

缺點

  • 請求的處理時間增加(要插入兩次,時間加倍)

  • 數據仍可能不一致,例如第二步寫入T1完成后服務重啟,則數據不會寫入T2

 

如果系統對處理時間比較敏感,引出常用的第二種方案。

 

三,服務異步雙寫


數據的雙寫並不再由服務來完成,服務層異步發出一個消息,通過消息總線發送給一個專門的數據復制服務來寫入冗余數據,如上圖1-6流程:

  • 業務方調用服務,新增數據

  • 服務先插入T1數據

  • 服務向消息總線發送一個異步消息(發出即可,不用等返回,通常很快就能完成)

  • 服務返回業務方新增數據成功

  • 消息總線將消息投遞給數據同步中心

  • 數據同步中心插入T2數據

 

優點

  • 請求處理時間短(只插入1次)

 

缺點

  • 系統的復雜性增加了,多引入了一個組件(消息總線)和一個服務(專用的數據復制服務)

  • 因為返回業務線數據插入成功時,數據還不一定插入到T2中,因此數據有一個不一致時間窗口(這個窗口很短,最終是一致的)

  • 在消息總線丟失消息時,冗余表數據會不一致

 

不管是服務同步雙寫,還是服務異步雙寫,服務都需要關注“冗余數據”帶來的復雜性。如果想解除“數據冗余”對系統的耦合,引出常用的第三種方案。

 

四,線下異步雙寫


為了屏蔽“冗余數據”對服務帶來的復雜性,數據的雙寫不再由服務層來完成,而是由線下的一個服務或者任務來完成,如上圖1-6流程:

  • 業務方調用服務,新增數據

  • 服務先插入T1數據

  • 服務返回業務方新增數據成功

  • 數據會被寫入到數據庫的log中

  • 線下服務或者任務讀取數據庫的log

  • 線下服務或者任務插入T2數據

 

優點

  • 數據雙寫與業務完全解耦

  • 請求處理時間短(只插入1次)

 

缺點

  • 返回業務線數據插入成功時,數據還不一定插入到T2中,因此數據有一個不一致時間窗口(這個窗口很短,最終是一致的)

  • 數據的一致性依賴於線下服務或者任務的可靠性

 

五,總結

互聯網數據量大的業務場景,常常:

    • 使用水平切分來降低單庫數據量

    • 使用數據冗余的反范式設計來滿足不同維度的查詢需求

    • 使用服務同步雙寫法能夠很容易的實現數據冗余

    • 為了降低時延,可以優化為服務異步雙寫法

    • 為了屏蔽“冗余數據”對服務帶來的復雜性,可以優化為線下異步雙寫法


免責聲明!

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



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