天天看點

從Binlog到Change Data Capture Solution

挖掘資料庫日志(Binlog)的方式,将資料庫變更實時、可靠的從資料庫拉取出來,業務可以通過定制化client實時擷取變更。分享個基于關系型資料庫日志增量訂閱的元件,調研圖

  • maxwells
  • debezium
  • canal
  • Databus
從Binlog到Change Data Capture Solution

Binlog

mysql有多種日志,常見的有:

  1. 錯誤日志(ErrorLog)
  2. 更新日志(UpdateLog)
  3. 二進制日志(Binlog)
  4. 查詢日志(QueryLog)
  5. 慢查詢日志(SlowQueryLog)

Binlog記錄了所有的DDL和DML(除了資料查詢語句)語句,以事件形式記錄,還包含語句所執行的消耗的時間,此外Binlog是事務安全型的。

Binlog一般作用是可以用于實時備份,與master/slave主從複制結合。

MySQL 主從複制原理的是啥?

  1. 主庫db的更新事件(update、insert、delete)被寫到binlog(二進制檔案)
  2. 從庫發起連接配接,連接配接到主庫
  3. 此時主庫建立一個binlog dump thread,把binlog的内容發送到從庫
  4. 從庫啟動之後,建立一個I/O線程,讀取主庫傳過來的binlog内容并寫入到relay log
  5. 從庫還會建立一個SQL線程,從relay log裡面讀取内容,從Exec_Master_Log_Pos位置開始執行讀取到的更新事件,将更新内容寫入到slave的db

可以知道,對于每一個主從複制的連接配接,都有三個線程。擁有多個從庫的主庫為每一個連接配接到主庫的從庫建立一個binlog輸出線程,每一個從庫都有它自己的I/O線程和SQL線程。

從Binlog到Change Data Capture Solution

資料丢失問題

如果主庫突然當機,恰好資料還沒同步到從庫,那麼有些資料可能在從庫上是沒有的?

MySQL 實際上在這一塊有兩個機制,一個是半同步複制,用來解決主庫資料丢失問題;一個是并行複制,用來解決主從同步延時問題。

半同步複制

也叫 

semi-sync

 複制,指的就是主庫寫入 binlog 日志之後,就會将強制此時立即将資料同步到從庫,從庫将日志寫入自己本地的 relay log 之後,接着會傳回一個 ack 給主庫,主庫接收到至少一個從庫的 ack 之後才會認為寫操作完成了。

并行複制

從庫開啟多個線程,并行讀取 relay log 中不同庫的日志,然後并行重放不同庫的日志,這是庫級别的并行,MySQL 5.6版本之前是這樣的。

主從同步延時問題

MySQL的複制延遲是一直被诟病的問題之一。MySQL 5.6版本前僅僅支援到庫級别的并行确實會導緻複制延遲問題。大家也可能遇到這樣的尴尬情況:先插入一條資料,再把它查出來,然後更新這條資料。在生産環境高峰期,寫并發達到了 2000/s,這個時候,主從複制延時大概是在小幾十毫秒。線上會發現,每天總有那麼一些資料,我們期望更新一些重要的資料狀态,但在高峰期時候卻沒更新。

show status
//檢視結果 Seconds_Behind_Master,可以看到從庫複制主庫的資料落後了幾 ms
           

一般來說,如果主從延遲較為嚴重,有以下解決方案:

  • 分庫,将一個主庫拆分為多個主庫,每個主庫的寫并發就減少了幾倍,此時主從延遲可以忽略不計
  • 打開 MySQL 支援的并行複制,多個庫并行複制。如果說某個庫的寫入并發就是特别高,單庫寫并發達到了 2000/s,并行複制還是沒意義
  • 适用場景有問題,如果确實是存在必須先插入,立馬要求就查詢到,然後立馬就要反過來執行一些操作,對這個查詢設定直連主庫。不推薦這種方法,你要是這麼搞,讀寫分離的意義就喪失了。

當然更新到MySQL 5.7是非常棒的!MySQL 5.7基于組送出的并行複制,可稱為真正的并行複制,并行複制的思想簡單易懂,一言以蔽之: 一個組送出的事務都是可以并行回放 ,因為這些事務都已進入到事務的prepare階段,則說明事務之間沒有任何沖突(否則就不可能送出)。這其中最為主要的原因就是slave伺服器的回放與主機是一緻的(master伺服器上是怎麼并行執行的slave上就怎樣進行并行回放)。不再有庫的并行複制限制,對于二進制日志格式也無特殊的要求(基于庫的并行複制也沒有要求)。從MySQL官方來看,其并行複制的原本計劃是支援表級的并行複制和行級的并行複制,行級的并行複制通過解析ROW格式的二進制日志的方式來完成, WL#4648 。但是最終出現給小夥伴的确是在開發計劃中稱為:MTS: Prepared transactions slave parallel applier,可見: WL#6314 。該并行複制的思想最早是由MariaDB的Kristain提出,并已在MariaDB 10中出現,相信很多選擇MariaDB的小夥伴最為看重的功能之一就是并行複制。

檢視主從複制狀态

當主從複制正在進行中時,如果想檢視從庫兩個線程運作狀态,可以通過執行在從庫裡執行”show slave status\G”語句,以下的字段可以給你想要的資訊:

Master_Log_File               上一個從主庫拷貝過來的binlog檔案

Read_Master_Log_Pos    主庫的binlog檔案被拷貝到從庫的relay log中的位置

Relay_Master_Log_File    SQL線程目前進行中的relay log檔案

Exec_Master_Log_Pos    目前binlog檔案正在被執行的語句的位置

總結,讀寫分離分散資料庫讀寫操作壓力,分庫分表分散存儲壓力。

從Binlog到Change Data Capture Solution

參考資料

  • Replication Implementation Details
  • What is MySQL Replication and How Does It Work?

繼續閱讀