MySQL異地多活數據雙向同步-CloudCanal實戰


簡述

異地多活是一項系統性工作,包含 web 層、應用服務層、數據層的流量分配和同步。

數據層的雙向同步是整個方案基礎,CloudCanal 在 MySQL <-> MySQL 鏈路有效支持了這個能力,本文簡要介紹如何使用 CloudCanal 配置這樣的雙向同步鏈路。

技術點

數據沖突

雙向同步中, 暫時無法完全通過數據層解決的問題是數據沖突,如一個訂單同時在兩地被修改價格,到底哪個為准,這個具有外部依賴性。

針對這個問題,最有效的解決方案是通過業務流量分配(比如user_id),將同一條數據(或相關數據)寫入放在其中一邊,更加簡單暴力的方式是將具備沖突條件的數據寫入完全放在一地。

另外同步工具層面可添加數據沖突策略,比如版本號對比、設定數據優先級等,甚至人工介入解決。

同步回環

回環問題,即防止數據在雙向鏈路中寫回產生日志的實例,導致老數據覆蓋新數據。

業界常用解決方案包括以下幾種:

修改數據庫引擎,將同步過來的日志寫入打上特殊標記(如 MySQL relay_log apply),對向鏈路識別該標記並決定是否同步

同步數據寫到對端時, 同一個事務帶上一個特定操作,對向鏈路識別這個操作,決定整個事務是否同步

依賴數據庫自身提供的防回環機制(比如 MySQL GTID),同步工具做相應動作

CloudCanal 目前在 MySQL 到 MySQL 鏈路采用了 GTID 方案,一是 MySQL 自帶這個防重能力,二是盡量避免做更多操作。

舉個 “栗子”

准備 CloudCanal

本次案例使用 docker 社區版,安裝文檔可以參考社區https://www.askcug.com 《CloudCanal社區版docker版安裝》文檔。

添加數據源

本案例 MySQL 數據庫放在上海杭州, CloudCanal社區版運行於上海 ECS

登錄 CloudCanal 平台

數據源管理 -> 添加數據源

選擇 自建 MySQL ,阿里雲 RDS 賬號權限不支持鏈接上設置 GTID_NEXT

 

 

 

自建 MySQL 開 binlog 和 GTID

server-id       = 2
log-bin         = mysql-bin
gtid_mode = on
enforce_gtid_consistency = on

確認 MySQL GTID 已經生效(請寫幾條測試數據)

 

 

 

建議對數據源進行描述修改,防止配置正反鏈路時,識別錯數據庫

 

 

 

創建正向同步任務

任務管理->新建任務

雙向同步中,正向任務一般指源端有數據,目標端無數據的鏈路,涉及對端數據初始化

源端和目標端選擇數據源, 並分別點擊 測試連接 按鈕以測試數據庫連通性和獲取 schema 級別元信息

選擇源端和目標端 schema

點擊下一步

 

 

 

選擇 數據同步,並且勾選 全量數據初始化

規格可以根據任務重要度以及部署機器的內存容量合理選擇,一般 2GB 內存規格即可

勾選 DDL 同步

點擊 下一步

 

 

 

表、列映射裁剪…此處省略

對任務內容進行確認 ,置灰 自動啟動任務 按鈕以便調參數

點擊確認創建

 

 

 

任務詳情 -> 參數設置

設置目標數據源配置 deCycle , enableTransaction , 源端數據源配置 gtidMode 參數為 true

 

 

 

生效配置並啟動

創建反向同步任務

任務管理->新建任務

源端和目標端選擇數據源(請和正向任務所選數據源對調, 並分別點擊 測試連接 按鈕以測試數據庫連通性和獲取 schema 級別元信息

選擇源端和目標端 schema

點擊下一步

 

 

 

選擇 數據同步,並去除 全量數據初始化

勾選 DDL 同步

點擊 下一步

 

 

 

表、列映射裁剪…此處省略

對任務內容進行確認 ,置灰 自動啟動任務 按鈕以便調參數

點擊確認創建

 

 

 

任務詳情 -> 參數設置

設置目標數據源配置 deCycle , enableTransaction , 源端數據源配置 gtidMode 參數為 true

生效配置並啟動

 

 

 

任務同步

正向任務和反向任務正常同步,進行源和目標數據校驗一致

 

 

 

測試

為了防止數據沖突,我們分別給兩個數據庫的不同表造一些混合負載,表級別隔離下沖突數據的可能。看最后數據是否一致。

給源端數據庫中 kbs_question 表和 目標數據庫 kbs_article 表造 IUD 負載 

 

 

 

停止測試負載

正向和反向任務狀況

 

 

 

 

 

 

重跑校驗任務,數據一致

 

 

 

FAQ

為什么不用 MySQL 原生的雙 Master 復制

如果對數據不做映射、裁剪、轉換、沖突策略(比如略過沖突數據)等動作,使用 MySQL 雙 Master 復制是一個選擇。

另外對於長距離雙向同步,還需做一些防網絡中斷等工作。

綜合這兩方面,第三方有商業支持或開源軟件可能會表現出更好的應變性。畢竟改 MySQL 代碼不容易。

為什么不用 Paxos 或 Raft 支持的數據庫異地 3 副本或 5 副本

一部分原因和上面是一致的,畢竟是數據庫內部機制,很難做一些定制。對於 3 副本或者 5 副本,一般做法是多數派副本在同城(不同機架、機房),少數副本在異地,異地副本靠異步同步數據。

對於單 Leader 寫入機制,連業務層面設計不沖突寫入策略的機會可能都沒有。Multi-Master 涉及更加復雜的算法。

綜合來看,沒有孰好孰壞,按業務對數據的實際要求和所能提供的硬件條件進行選擇。

雙向同步還支持哪些鏈路?

目前 CloudCanal 方案只實現了 MySQL->MySQL ,並且方案上依賴 GTID ,對於 ORACLE ,PG ,SQLSERVER 等關系型數據庫,可能需要實現通用方案(主要是事務方案), 將他們同構或者異構鏈接起來。

總結

本文簡單介紹了如何使用 CloudCanal 構建 MySQL->MySQL 雙向同步鏈路,如果各位有需求,可以嘗試使用下我們的免費社區版體驗。

 


免責聲明!

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



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