下載網站: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 接口,方便擴展
設計實現如下
整體架構
基本原理可以將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
設置入隊規則的步驟基本如下:
1. 新建隊列,比如 all-users-binlog
2. 在指定exchange中建立綁定關系,如上圖示例
表過濾Binlog事件dump過程中會得到數據庫中所有表的變更記錄。在實際使用中,可能只需要關注特定表(比如訂單表)的變更事件。為了提升性能,引入了事件過濾邏輯,通過配置對應數據庫+表名,過濾binlog事件。
比如配置過濾邏輯為admin.orders,消息接收器收到消息只會包含orders表的消息。
對於數據庫物理分表,比如當數據庫訂單表分了100張子表的時候,這時候配置過濾邏輯會是一件麻煩的事情。為了避免配置多個表,引入前綴匹配邏輯,只需要保證分表前綴相同,即可簡化為一條配置。比如訂單分表配置可以簡化為admin.orders_{suffix},這樣配置之后,只要匹配orders_前綴的表,均可以捕獲到變化,這里的“{suffix}”是固定值,不能更改。
過濾邏輯可見上面面示意圖,圖中pos:1018為事件在MySQL binlog中的位置點,位置點小代表SQL執行順序靠前。
你可能會注意到上文提到的RabbitMQ,如果我們只綁定特定的表,也可以達到同樣目的。但是這樣做有2個缺點:
- 會增加無用的消息發送
- 性能會有損耗,增加無效事件解析
當然如果想監聽從庫所有事件,不配置表過濾即可
平滑重啟實際生產環境使用過程中,如果重啟程序后,不能從上次停止的binlog 位置讀取,重啟期間數據庫(此時監聽數據庫保持運行)增量數據就會丟失。為了避免上述問題,實例運行期間每隔5秒定時保存已發送成功的binlog節點位置,程序重啟自動讀取上次保存的位置節點繼續解析binlog事件,當然這樣會帶來數據重復,需要業務使用者保證消息的冪等。
高可用正常情況下,監聽一個從庫只需要啟動一個CDC實例,但如果此時機器宕機,就會造成服務不可用,這種異常情況在生產環境沒有容錯方案是不合理的。
為了保證CDC服務的高可用,會同時在多台服務器啟動CDC,並引入分布式鎖,保證同時只有一個實例連接到MySQL解析Binary Log,其他的實例為備選。如果主節點宕機,則備選節點通過競爭獲取到鎖,連接到MySQL,保證服務繼續使用。
運行步驟如下:
- 嘗試獲取分布式鎖
- 獲取成功,則連接數據庫,獲取Binary log事件流
- 獲取失敗,則主線程等待5秒后,回到第1步
表過濾配置動態加載程序重啟會導致數據延時(分鍾級別),要盡量避免不必要的程序重啟。
生產環境中經常遇到這樣的場景,給某個實例新加一張表,如果要讓新加的過濾配置生效,就需要重啟程序。顯然這種頻繁變更的配置,需要通過重啟程序來生效是不合理的。
因此CDC支持動態添加表和刪除表過濾配置,實時生效。
監控和平台化隨着更多業務線接入CDC,對CDC的管理成為棘手的事情,如不知道實例具體在哪台機器運行,運行是否正常(位置點是否更新),配置管理更新和業務接入等等。
主要通過下面2點來解決管理問題:
- 實例運行注冊制,監控實例運行狀態。
- 配置和數據中心化存儲,動態下發來規范配置管理。
化分布式鎖、配置存儲、加載上訴分布式鎖和數據存儲,歷史版本是通過redis來實現,但是redis並不適合這樣高可用場景。
綜合考慮,開源版本選用 ETCD,ETCD 是一個高可用、強一致性的服務發現存儲倉庫。CDC通過ETCD主要實現下面幾個功能:
- 服務注冊
- 分布式鎖
- 保存binlog名字和位置節點
- 配置管理
- 配置動態加載(reload)
消息格式消息包含3種類型:
insert,update,delete。
數據示例:
- INSERT
{
“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
{
“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
{
“database”:”test”,
“createtime”:1525319817439,
“data”:{
“id”:”6″
},
“action”:”delete”,
“uniqid”:”9f0460b56a10fe87713093d13c2b7226″,
“table”:”cdctest”
}
總結
以上就是CDC工具的設計思路。通過該工具,MySQL數據同步問題可以很方便的解決。