基於MySQL的高可用准實時的數據同步方案


下載網站:www.SyncNavigator.CN 
 客服QQ1793040
----------------------------------------------------------


關於HKROnline SyncNavigator 注冊機價格的問題

 

 

HKROnline SyncNavigator 8.4.1 非破解版 注冊機 授權激活教程
 

 

隨着公司業務的發展,經常需要做一些數據同步或者數據變化監控的工作,舉例:

1.  訂單數據需要同步到其他業務系統

2.  業務數據需要同步到數據分析部門做分析

3.  數據庫的數據需要同步到全文搜索引擎

經常使用的方法有如下幾種:

1.  保持雙寫,即更新數據同時,更新緩存,更新搜索,提交數據到其他業務線

2.  通過定時任務掃表同步

3.  引入消息隊列,生產者與消費者分開處理

以上的方案多多少少都存在一些弊端:無法保證雙寫成功,影響核心業務代碼可讀性,難以保證實時性等。

由於公司主要的存儲是MySQL,因此 融360技術團隊 引入CDC(change data capture)解析MySQL  Binlog,解決以上問題。目前在公司有以下業務場景使用:

1.  消息的pub/sub

2.  異構數據的同步

3.  MySQL在線 DDL

4.  MySQL在線分庫/分表的平滑遷移

5.  大數據准實時ETL

業界方案目前也有許多方案支持MySQL日志解析,但如果要用於生產環境,主要存在幾個問題。

 

1.  單點問題,缺少高可用支持

2.  重啟程序不平滑

3.  不支持表過濾,比如只需要監控特定表的場景

4.  缺乏完善的監控

5.  缺乏多集群多實例的統一管理

6.  使用不夠方便友好

項目介紹CDC基於MySQL數據庫增量日志解析,將MySQL Binary Log事件(插入/刪除/更新)轉換為JSON格式數據發送到RabbitMQ或其他MQ(如Kafka),業務端只需要進行增量數據訂閱和消費。目前已經在超過10個MySQL實例上穩定運行超過36個月。其中MySQL日志協議解析基於開源項目:

 

https://github.com/shyiko/mysql-binlog-connector-java

Features

  • 高可用,集群部署
  • 表級別過濾
  • 支持幾乎所有MySQL字段解析(MySQL 5.6以上版本未完全覆蓋測試)
  • 自動保存Binary Log位置節點,平滑升級重啟,數據保證高可用
  • 配置集中化管理
  • 運行狀態監控
  • 動態加載表配置
  • 支持添加多個導出數據源,方便擴展到其他消息隊列
  • 支持順序優先/性能優先,可根據業務特點選擇使用
  • 支持 RESTFUL 接口,方便擴展

設計實現如下

整體架構基於MySQL的高可用准實時的數據同步方案

 

基本原理可以將CDC看作是一台從庫,它會向主庫發送 binlog dump 指令,主庫就會將 binlog event 源源不斷的發送過來。

 

主線程解析binlog事件,保存到內存隊列,工作線程讀取對應隊列事件,分發事件。

分發策略根據業務場景不同,提供2種發送策略:

 

1.  多個線程分發事件(不會嚴格按照SQL執行順序),提高分發效率,保證性能,側重於關注數據變化的場景

2.  保證事件到達順序,單線程發送事件,側重於對准確性要求極高的場景

消息接收器通過注冊不同消息接收器,來支持發送到不同MQ。支持注冊多個消息接收器。消息接收器如果有特殊需求可以實現定制化。

 

下面主要介紹下RabbitMQ消息接收器原理。

注冊RabbitMQ消息接收器后,CDC會將消息發送到RabbitMQ的一個 TOPIC 類型的exchange中。

根據消息對應的routing key,非常方便的將消息發送到指定的隊列中。routing key生成規則為:

 database(數據庫名).table(表名).action(對應動作,insert/update/delete)

如果是分表,為了避免在rabbitmq中添加多個綁定關系。routingkey生成規則為:

database(數據庫名).{table(表名前綴)}.action(對應動作,insert/update/delete)

比如數據庫admin中orders分表為orders_1,orders_2,則對應的routingkey為admin.{orders_}.action

基於MySQL的高可用准實時的數據同步方案

設置入隊規則的步驟基本如下:

1.  新建隊列,比如 all-users-binlog

2.  在指定exchange中建立綁定關系,如上圖示例

表過濾Binlog事件dump過程中會得到數據庫中所有表的變更記錄。在實際使用中,可能只需要關注特定表(比如訂單表)的變更事件。為了提升性能,引入了事件過濾邏輯,通過配置對應數據庫+表名,過濾binlog事件。

 

基於MySQL的高可用准實時的數據同步方案

比如配置過濾邏輯為admin.orders,消息接收器收到消息只會包含orders表的消息。

對於數據庫物理分表,比如當數據庫訂單表分了100張子表的時候,這時候配置過濾邏輯會是一件麻煩的事情。為了避免配置多個表,引入前綴匹配邏輯,只需要保證分表前綴相同,即可簡化為一條配置。比如訂單分表配置可以簡化為admin.orders_{suffix},這樣配置之后,只要匹配orders_前綴的表,均可以捕獲到變化,這里的“{suffix}”是固定值,不能更改。

過濾邏輯可見上面面示意圖,圖中pos:1018為事件在MySQL binlog中的位置點,位置點小代表SQL執行順序靠前。

你可能會注意到上文提到的RabbitMQ,如果我們只綁定特定的表,也可以達到同樣目的。但是這樣做有2個缺點:

  1. 會增加無用的消息發送
  2. 性能會有損耗,增加無效事件解析

當然如果想監聽從庫所有事件,不配置表過濾即可

平滑重啟實際生產環境使用過程中,如果重啟程序后,不能從上次停止的binlog 位置讀取,重啟期間數據庫(此時監聽數據庫保持運行)增量數據就會丟失。為了避免上述問題,實例運行期間每隔5秒定時保存已發送成功的binlog節點位置,程序重啟自動讀取上次保存的位置節點繼續解析binlog事件,當然這樣會帶來數據重復,需要業務使用者保證消息的冪等。

 

高可用正常情況下,監聽一個從庫只需要啟動一個CDC實例,但如果此時機器宕機,就會造成服務不可用,這種異常情況在生產環境沒有容錯方案是不合理的。

 

為了保證CDC服務的高可用,會同時在多台服務器啟動CDC,並引入分布式鎖,保證同時只有一個實例連接到MySQL解析Binary Log,其他的實例為備選。如果主節點宕機,則備選節點通過競爭獲取到鎖,連接到MySQL,保證服務繼續使用。

基於MySQL的高可用准實時的數據同步方案

運行步驟如下:

  1. 嘗試獲取分布式鎖
  2. 獲取成功,則連接數據庫,獲取Binary log事件流
  3. 獲取失敗,則主線程等待5秒后,回到第1步

表過濾配置動態加載程序重啟會導致數據延時(分鍾級別),要盡量避免不必要的程序重啟。

 

生產環境中經常遇到這樣的場景,給某個實例新加一張表,如果要讓新加的過濾配置生效,就需要重啟程序。顯然這種頻繁變更的配置,需要通過重啟程序來生效是不合理的。

因此CDC支持動態添加表和刪除表過濾配置,實時生效。

監控和平台化隨着更多業務線接入CDC,對CDC的管理成為棘手的事情,如不知道實例具體在哪台機器運行,運行是否正常(位置點是否更新),配置管理更新和業務接入等等。

 

主要通過下面2點來解決管理問題:

  1. 實例運行注冊制,監控實例運行狀態。
  2. 配置和數據中心化存儲,動態下發來規范配置管理。

化分布式鎖、配置存儲、加載上訴分布式鎖和數據存儲,歷史版本是通過redis來實現,但是redis並不適合這樣高可用場景。

 

綜合考慮,開源版本選用 ETCD,ETCD 是一個高可用、強一致性的服務發現存儲倉庫。CDC通過ETCD主要實現下面幾個功能:

  1. 服務注冊
  2. 分布式鎖
  3. 保存binlog名字和位置節點
  4. 配置管理
  5. 配置動態加載(reload)

消息格式消息包含3種類型:

 

insert,update,delete。

數據示例:

  • INSERT

基於MySQL的高可用准實時的數據同步方案

基於MySQL的高可用准實時的數據同步方案{

“database”:”test”,
“createtime”:1525319434400,
“data”:{
“longtext”:”test longtext”,
“date”:”1556121600000″,
“year”:”2019″,
“bit”:”1″,
“point”:”POINT (123.46202 41.2301)”,
“smallint”:”23″,
“datetime”:”1556007145000″,
“text”:”test text”,
“fload”:”5.55″,
“bigint”:”55″,
“tinyblob”:”測試test tinyblob”,
“timestamp”:”1524801357000″,
“multipoint”:”POINT (123.46222 41.201)”,
“mediumint”:”5″,
“set”:”a,c,d”,
“mediumtext”:”test mediumtext”,
“double”:”5.555″,
“tinytext”:”test tinytext”,
“varchar”:”test varchar”,
“tinyint”:”7″,
“multilinestring”:”LINESTRING (0 0, 13 16)”,
“id”:”6″,
“enum”:”a”,
“mediumblob”:”測試test mediumblob”,
“varbinary”:”convert(binary,’8280′)”,
“multipolygon”:”POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (5 5, 7 5, 7 7, 5 7, 5 5))”,
“blob”:”測試test ccblob”,
“polygon”:”POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (4 4, 7 4, 7 7, 4 7, 4 4))”,
“binary”:”convert(binary,’828′)”,
“char”:”test char”,
“longblob”:”測試test longblob”,
“geometry”:”POINT (108.998710632 34.258825935)”,
“time”:”-10800000″,
“geometrycollection”:”POINT (10 30)”,
“decimal”:”5.56″,
“linestring”:”LINESTRING (0 0, 10 10, 20 25)”
},
“action”:”insert”,
“uniqid”:”fe5be0ecaee15e7331a9c841df5c0b91″,
“table”:”cdctest”
}

  • UPDATE

基於MySQL的高可用准實時的數據同步方案

{

“database”:”test”,
“createtime”:1525319725963,
“data”:{
“before”:{
“id”:”6″
},
“after”:{
“mediumint”:”3″,
“decimal”:”5.50″,
“bigint”:”2″,
“timestamp”:”1525319725000″
}
},
“action”:”update”,
“uniqid”:”8e9c8af3acc6a7e6ff0d6c23608b4eaf”,
“table”:”cdctest”
}

  • DELETE

基於MySQL的高可用准實時的數據同步方案

{

“database”:”test”,
“createtime”:1525319817439,
“data”:{
“id”:”6″
},
“action”:”delete”,
“uniqid”:”9f0460b56a10fe87713093d13c2b7226″,
“table”:”cdctest”
}

基於MySQL的高可用准實時的數據同步方案

       總結

以上就是CDC工具的設計思路。通過該工具,MySQL數據同步問題可以很方便的解決。


免責聲明!

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



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