MySQL 數據庫主從復制架構


前文《MySQL 數據庫事務與復制》分析了 MySQL 復制過程中如何保證 binlog 和事務數據之間的一致性,本文進一步分析引入從庫后需要保證主從的數據一致性需要考慮哪些方面。

原生復制架構

MySQL 的原生復制架構原理如上圖所示。從庫的 I/O Thread 線程負責不斷讀取主庫的 binlog 日志文件並寫入本地的 Relay log 臨時緩存。從庫的 SQL Thread 線程則不斷讀取 Relay log 重放事件入庫。整個過程看起來是比較簡單清晰的,但其中有幾個點對主從數據一致性有關鍵影響,我們下面逐一分析。

主從復制的場景下,產生數據不一致的現象有兩種:

  1. 數據丟失
  2. 數據重復

從庫的 I/O Thread 是通過網絡讀取主庫的 binlog 的,若出現網絡故障,有可能產生數據丟失。為避免網絡故障導致的數據丟失,網絡恢復后從庫重新連接上來需要知道從主庫 binlog 的哪個位置重新傳輸數據。從庫需要記住中斷發生時 binlog 的位置,並從該斷點處重新讀取,這個斷點我們稱為從庫的重傳檢查點。一個可靠的重傳檢查點必須是在從庫讀到數據並寫入到本地 Relay log 持久化之后才可建立,否則都有丟失數據的可能。

由於主從復制過程的分布式特征,需要保證復制過程的冪等性,也就是重復復制同一條數據最終不會產生重復的數據。防重策略是必須的,一般符合范式特征的數據庫表設計通過主鍵來防重,而無主鍵表數據可以通過所有字段聯合唯一索引來防重。有了防重策略就可以任意回溯復制過程,而不必考慮從庫產生重復數據。

為了保證主從數據一致性,復制過程不僅要保證不丟失、不重復,還需要保證操作順序一致。binlog 的事件日志反應了主庫並發事務的操作序列,最終這種序列也要原樣反應到從庫上。所以原生復制架構為了做到這點,采用了單線程模型的串行化操作。這也是沒辦法的,因為在數據庫層面是無法知道不同數據之間的因果和依賴關系,因此無法並行入庫。

原生的復制架構做到了無丟失、無重復和順序一致性,普通場景下基本可用,但也存在一些不足:

  • 可監控性、可管理性相對較弱。
  • 對於異構數據無能為力。
  • 通用的單線程模型可能成為性能瓶頸,導致復制延時過高。
  • 一對多場景下對主庫形成過大復制壓力,影響主庫可用性。

一些特殊場景下的數據庫復制分布,使用原生復制架構則不一定合適,可能的場景有:

  • 大型庫,數據量大,寫入量大,還需要跨地域、跨機房的復制,而且對復制延時長短比較敏感,比如大型電商的訂單、交易類數據庫。

所以我們才需要考慮針對特殊場景自定義復制架構,下面我們看一個自定義復制架構的概念原理圖。

自定義復制架構

如上,自定義復制架構參考原生架構模擬成一個 MySQL 從庫,它內部包括三個主要角色:

  1. Pull Worker,作用類似於原生的 I/O Thread。
  2. Buffer + Persistent Storage,作用類似於原生的 Relay log。
  3. Load Worker,作用類似於原生的 SQL Thread。

由於是自定義程序實現則可以在無改造 MySQL 的前提下提供額外的功能,相對應用和 MySQL 都可以做到透明。相對原生復制架構的不足,自定義復制架構可以提供更好的復制過程監控和管理能力,並支持異構數據轉換等等。而對於需要跨地域、跨機房且延時敏感的大型庫復制,則可以通過適當的策略來加速復制過程。

比如前面提到的大型電商的訂單、交易類數據庫,一般都是分庫分表的。分庫分表后,不同庫表之間的數據其實在業務上是完全獨立的,是可以支持並行寫入的。所以我們看上圖為什么畫了兩個 Load Worker,就是表達可以針對業務獨立的表進行並行寫入。一條數據的復制延時包括:

總時長 T = P + N + L; 其中 P 是 Pull Worker 處理時長,N 是網絡傳輸時長, L 是 Load Worker 處理時長。

同一個庫的 binlog 是順序的不好並行拉取,傳輸過程的網絡時長也是剛性的,唯一能加速的就是入庫處理。按業務獨立的不同表可以做到並行的多線程入庫操作,以縮短 L 的整體時長,如下圖所示。

總結

本文分析了 MySQL 基於 binlog 的主從復制原理,從數據一致性的角度考慮分布式網絡環境下主從架構設計的關鍵要素。在分析了 MySQL 原生復制架構的基礎上給出了一個靈活性和可控性更高的自定義復制架構的高層設計。理解了主從復制架構如何保證數據一致性后,我們后面才可進一步考慮在雙寫主庫的場景如何做雙向復制同步並保證雙主庫的數據最終一致性問題。這個系列下一篇文章會專門分析這個問題。

參考

[1] MySQL Internals Manual. Replication.
[2] MySQL Internals Manual. The Binary Log.
[3] in355hz. 數據庫 ACID 的實現.
[4] jb51. MySQL 對 binlog 的處理說明.
[5] repls. 淺析 innodb_support_xa 與 innodb_flush_log_at_trx_commit.
[6] 68idc. MySQL 5.6 之 DBA 與開發者指南.
[7] csdn. 高性能 MySQL 主從架構的復制原理及配置詳解


下面是我的微信公眾號 「瞬息之間」,除了寫技術的文章、還有產品、行業和人生的思考,希望能和更多走在這條路上同行者交流。


免責聲明!

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



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