Canal:同步mysql增量數據工具,一篇詳解核心知識點

Canal 實時同步

首先我們要配置環境,在 conf/example/instance.properties 下:

## mysql serverId

canal.instance.mysql.slaveId = 1234

#position info,需要修改成自己的數據庫信息

canal.instance.master.address = 127.0.0.1:3306

canal.instance.master.journal.name =

canal.instance.master.position =

canal.instance.master.timestamp =

#canal.instance.standby.address =

#canal.instance.standby.journal.name =

#canal.instance.standby.position =

#canal.instance.standby.timestamp =

#username/password,需要修改成自己的數據庫信息

canal.instance.dbUsername = canal

canal.instance.dbPassword = canal

canal.instance.defaultDatabaseName =

canal.instance.connectionCharset = UTF-8

#table regex

canal.instance.filter.regex = .\*\\\\..\*

其中,canal.instance.connectionCharset 代表數據庫的編碼方式對應到 java 中的編碼類型,比如 UTF-8,GBK,ISO-8859-1。

配置完后,就要啟動了

sh bin/startup.sh

關閉使用 bin/stop.sh

觀察日志

一般使用 cat 查看 canal/canal.log、example/example.log

啟動客戶端

在 IDEA 中業務代碼,mysql 中如果有增量數據就拉取過來,在 IDEA 控制臺打印出來

在 pom.xml 文件中添加:

<dependency>

? <groupId>com.alibaba.otter</groupId>

? <artifactId>canal.client</artifactId>

? <version>1.0.12</version>

</dependency>

添加客戶端代碼:

public class Demo {

public static void main(String[] args) {

? ? //創建連接

? ? CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress("hadoop03", 11111),

? ? ? ? ? ? "example", "", "");

? ? connector.connect();

? ? //訂閱

? ? connector.subscribe();

? ? connector.rollback();

? ? int batchSize = 1000;

? ? int emptyCount = 0;

? ? int totalEmptyCount = 100;

? ? while (totalEmptyCount > emptyCount) {

? ? ? ? Message msg = connector.getWithoutAck(batchSize);

? ? ? ? long id = msg.getId();

? ? ? ? List<CanalEntry.Entry> entries = msg.getEntries();

? ? ? ? if(id == -1 || entries.size() == 0){

? ? ? ? ? ? emptyCount++;

? ? ? ? ? ? System.out.println("emptyCount : " + emptyCount);

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? Thread.sleep(3000);

? ? ? ? ? ? } catch (InterruptedException e) {

? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? }

? ? ? ? }else{

? ? ? ? ? ? emptyCount = 0;

? ? ? ? ? ? printEntry(entries);

? ? ? ? }

? ? ? ? connector.ack(id);

? ? }

}

// batch -> entries -> rowchange - rowdata -> cols

private static void printEntry(List<CanalEntry.Entry> entries) {

? ? for (CanalEntry.Entry entry : entries){

? ? ? ? if(entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONBEGIN ||

? ? ? ? ? ? ? ? entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONEND){

? ? ? ? ? ? continue;

? ? ? ? }

? ? ? ? CanalEntry.RowChange rowChange = null;

? ? ? ? try {

? ? ? ? ? ? rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue());

? ? ? ? } catch (InvalidProtocolBufferException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? }

? ? ? ? CanalEntry.EventType eventType = rowChange.getEventType();

? ? ? ? System.out.println(entry.getHeader().getLogfileName()+" __ " +

? ? ? ? ? ? ? ? entry.getHeader().getSchemaName() + " __ " + eventType);

? ? ? ? List<CanalEntry.RowData> rowDatasList = rowChange.getRowDatasList();

? ? ? ? for(CanalEntry.RowData rowData : rowDatasList){

? ? ? ? ? ? for(CanalEntry.Column column: rowData.getAfterColumnsList()){

? ? ? ? ? ? ? ? System.out.println(column.getName() + " - " +

? ? ? ? ? ? ? ? ? ? ? ? column.getValue() + " - " +

? ? ? ? ? ? ? ? ? ? ? ? column.getUpdated());

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

}

在mysql中寫數據,客戶端就會把增量數據打印到控制臺。

Canal 的 HA 機制設計

在大數據領域很多框架都會有 HA 機制,Canal 的 HA 分為兩部分,Canal server 和 Canal client 分別有對應的 HA 實現:

canal server:為了減少對 mysql dump 的請求,不同 server 上的 instance 要求同一時間只能有一個處于 running,其他的處于 standby 狀態。

canal client:為了保證有序性,一份 instance 同一時間只能由一個 canal client 進行 get/ack/rollback 操作,否則客戶端接收無法保證有序。

整個 HA 機制的控制主要是依賴了 ZooKeeper 的幾個特性,ZooKeeper 這里就不講了。

Canal Server:

canal server 要啟動某個 canal instance 時都先向 ZooKeeper 進行一次嘗試啟動判斷(創建 EPHEMERAL 節點,誰創建成功就允許誰啟動)。

創建 ZooKeeper 節點成功后,對應的 canal server 就啟動對應的 canal instance,沒有創建成功的 canal instance 就會處于 standby 狀態。

一旦 ZooKeeper 發現 canal server 創建的節點消失后,立即通知其他的 canal server 再次進行步驟 1 的操作,重新選出一個 canal server 啟動 instance。

canal client 每次進行 connect 時,會首先向 ZooKeeper 詢問當前是誰啟動了 canal instance,然后和其建立連接,一旦連接不可用,會重新嘗試 connect。

canal client 的方式和 canal server 方式類似,也是利用 ZooKeeper 的搶占 EPHEMERAL 節點的方式進行控制。

Canal HA 的配置,并把數據實時同步到 kafka 中。

修改 conf/canal.properties 文件

canal.zkServers = hadoop02:2181,hadoop03:2181,hadoop04:2181

canal.serverMode = kafka

canal.mq.servers = hadoop02:9092,hadoop03:9092,hadoop04:9092

配置 conf/example/example.instance

? canal.instance.mysql.slaveId = 790 /兩臺canal server的slaveID唯一

? canal.mq.topic = canal_log //指定將數據發送到kafka的topic

數據同步方案總結

講完了 Canal 工具,現在給大家簡單總結下目前常見的數據采集工具,不會涉及架構知識,只是簡單總結,讓大家有個印象。

常見的數據采集工具有:DataX、Flume、Canal、Sqoop、LogStash 等。

DataX (處理離線數據)

DataX 是阿里巴巴開源的一個異構數據源離線同步工具,異構數據源離線同步指的是將源端數據同步到目的端,但是端與端的數據源類型種類繁多,在沒有 DataX 之前,端與端的鏈路將組成一個復雜的網狀結構,非常零散無法把同步核心邏輯抽象出來。

為了解決異構數據源同步問題,DataX 將復雜的網狀的同步鏈路變成了星型數據鏈路,DataX 作為中間傳輸載體負責連接各種數據源。

所以,當需要接入一個新的數據源的時候,只需要將此數據源對接到 DataX,就可以跟已有的數據源做到無縫數據同步。

DataX本身作為離線數據同步框架,采用Framework+plugin架構構建。將數據源讀取和寫入抽象成為Reader/Writer插件,納入到整個同步框架中。

Reader: 它為數據采集模塊,負責采集數據源的數據,將數據發送給Framework。

Writer: 它為數據寫入模塊,負責不斷向Framework取數據,并將數據寫入到目的端。

Framework:它用于連接Reader和Writer,作為兩者的數據傳輸通道,并處理緩沖、并發、數據轉換等問題。

DataX的核心架構如下圖:

核心模塊介紹:

DataX完成單個數據同步的作業,我們把它稱之為Job,DataX接收到一個Job之后,將啟動一個進程來完成整個作業同步過程。

DataX Job啟動后,會根據不同的源端切分策略,將Job切分成多個小的Task(子任務),以便于并發執行。

切分多個Task之后,DataX Job會調用Scheduler模塊,根據配置的并發數據量,將拆分成的Task重新組合,組裝成TaskGroup(任務組)。每一個TaskGroup負責以一定的并發運行完畢分配好的所有Task,默認單個任務組的并發數量為5。

每一個Task都由TaskGroup負責啟動,Task啟動后,會固定啟動Reader->Channel->Writer的線程來完成任務同步工作。

DataX作業運行完成之后,Job監控并等待多個TaskGroup模塊任務完成,等待所有TaskGroup任務完成后Job成功退出。否則,異常退出。

Flume(處理實時數據)

Flume主要應用的場景是同步日志數據,主要包含三個組件:Source、Channel、Sink。

Flume最大的優點就是官網提供了豐富的Source、Channel、Sink,根據不同的業務需求,我們可以在官網查找相關配置。另外,Flume還提供了自定義這些組件的接口。

Logstash(處理離線數據)

Logstash就是一根具備實時數據傳輸能力的管道,負責將數據信息從管道的輸入端傳輸到管道的輸出端;與此同時這根管道還可以讓你根據自己的需求在中間加上過濾網,Logstash提供了很多功能強大的過濾網來滿足各種應用場景。

Logstash是由JRuby編寫,使用基于消息的簡單架構,在JVM上運行。在管道內的數據流稱之為event,它分為inputs階段、filters階段、outputs階段。

USB Microphone https://www.soft-voice.com/

Wooden Speakers? https://www.zeshuiplatform.com/

亞馬遜測評 www.yisuping.cn

深圳網站建設www.sz886.com

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容