Flink CDC 系列 - 實現 MySQL 資料實時寫入 Apache Doris

ApacheFlink發表於2021-12-09

本文通過例項來演示怎麼通過 Flink CDC 結合 Doris 的 Flink Connector 實現從 Mysql 資料庫中監聽資料並實時入庫到 Doris 數倉對應的表中。主要內容包括:

  1. 什麼是 CDC
  2. Flink CDC
  3. 什麼是 Flink Doris Connector
  4. 用法示例

Flink 中文學習網站
https://flink-learning.org.cn

一、什麼是 CDC

CDC 是變更資料捕獲 (Change Data Capture) 技術的縮寫,它可以將源資料庫 (Source) 的增量變動記錄,同步到一個或多個資料目的 (Sink)。在同步過程中,還可以對資料進行一定的處理,例如分組 (GROUP BY)、多表的關聯 (JOIN) 等。

例如對於電商平臺,使用者的訂單會實時寫入到某個源資料庫;A 部門需要將每分鐘的實時資料簡單聚合處理後儲存到 Redis 中以供查詢,B 部門需要將當天的資料暫存到 Elasticsearch 一份來做報表展示,C 部門也需要一份資料到 ClickHouse 做實時數倉。隨著時間的推移,後續 D 部門、E 部門也會有資料分析的需求,這種場景下,傳統的拷貝分發多個副本方法很不靈活,而 CDC 可以實現一份變動記錄,實時處理並投遞到多個目的地。

CDC 的應用場景

  • 資料同步:用於備份,容災;
  • 資料分發:一個資料來源分發給多個下游系統;
  • 資料採集:面向資料倉儲 / 資料湖的 ETL 資料整合,是非常重要的資料來源。

CDC 的技術方案非常多,目前業界主流的實現機制可以分為兩種:

  • 基於查詢的 CDC

    • 離線排程查詢作業,批處理。把一張表同步到其他系統,每次通過查詢去獲取表中最新的資料;
    • 無法保障資料一致性,查的過程中有可能資料已經發生了多次變更;
    • 不保障實時性,基於離線排程存在天然的延遲。
  • 基於日誌的 CDC

    • 實時消費日誌,流處理,例如 MySQL 的 binlog 日誌完整記錄了資料庫中的變更,可以把 binlog 檔案當作流的資料來源;
    • 保障資料一致性,因為 binlog 檔案包含了所有歷史變更明細;
    • 保障實時性,因為類似 binlog 的日誌檔案是可以流式消費的,提供的是實時資料。

二、Flink CDC

Flink 在 1.11 版本中新增了 CDC 的特性,簡稱改變資料捕獲。名稱來看有點亂,我們先從之前的資料架構來看 CDC 的內容。

img

以上是之前的 mysq binlog 日誌處理流程,例如 canal 監聽 binlog 把日誌寫入到 kafka 中。而 Apache Flink 實時消費 Kakfa 的資料實現 mysql 資料的同步或其他內容等。拆分來說整體上可以分為以下幾個階段:

  1. Mysql 開啟 binlog;
  2. Canal 同步 binlog 資料寫入到 Kafka;
  3. Flink 讀取 Kakfa 中的 binlog 資料進行相關的業務處理。

整體的處理鏈路較長,需要用到的元件也比較多。Apache Flink CDC 可以直接從資料庫獲取到 binlog 供下游進行業務計算分析

Flink Connector Mysql CDC 2.0 特性

提供 MySQL CDC 2.0,核心 feature 包括:

  • 併發讀取,全量資料的讀取效能可以水平擴充套件;
  • 全程無鎖,不對線上業務產生鎖的風險;
  • 斷點續傳,支援全量階段的 checkpoint。

網上有測試文件顯示用 TPC-DS 資料集中的 customer 表進行了測試,Flink 版本是 1.13.1,customer 表的資料量是 6500 萬條,Source 併發為 8,全量讀取階段:

  • MySQL CDC 2.0 用時 13 分鐘;
  • MySQL CDC 1.4 用時 89 分鐘;
  • 讀取效能提升 6.8 倍。

三、什麼是 Flink Doris Connector

Flink Doris Connector 是 Doris 社群為了方便使用者使用 Flink 讀寫 Doris 資料表的一個擴充套件,目前 Doris 支援 Flink 1.11.x ,1.12.x,1.13.x;Scala 版本:2.12.x。

目前 Flink Doris connector 目前控制入庫通過兩個引數:

  1. sink.batch.size:每多少條寫入一次,預設 100 條;
  2. sink.batch.interval :每個多少秒寫入一下,預設 1 秒。

這兩引數同時起作用,哪個條件先到就觸發寫 Doris 表操作,

注意:

這裡注意的是要啟用 http v2 版本,具體在 fe.conf 中配置 enable_http_server_v2=true,同時因為是通過 fe http rest api 獲取 be 列表,這倆需要配置的使用者有 admin 許可權。

四、用法示例

4.1 Flink Doris Connector 編譯

首先我們要編譯 Doris 的 Flink connector,也可以通過下面的地址進行下載:

https://github.com/hf200012/h...

注意:

這裡因為 Doris 的 Flink Connector 是基於 Scala 2.12.x 版本進行開發的,所以你在使用 Flink 的時候請選擇對應 Scala 2.12 的版本,如果你使用上面地址下載了相應的 jar,請忽略下面的編譯內容部分。

在 Doris 的 docker 編譯環境 apache/incubator-doris:build-env-1.2 下進行編譯,因為 1.3 下面的 JDK 版本是 11,會存在編譯問題。

在 extension/flink-doris-connector/ 原始碼目錄下執行:

sh build.sh

編譯成功後,會在 output/ 目錄下生成檔案 doris-flink-1.0.0-SNAPSHOT.jar。將此檔案複製到 FlinkClassPath 中即可使用 Flink-Doris-Connector。例如,Local 模式執行的 Flink,將此檔案放入 jars/ 資料夾下。Yarn 叢集模式執行的 Flink,則將此檔案放入預部署包中。

針對 Flink 1.13.x 版本適配問題

   <properties>
        <scala.version>2.12</scala.version>
        <flink.version>1.11.2</flink.version>
        <libthrift.version>0.9.3</libthrift.version>
        <arrow.version>0.15.1</arrow.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <doris.home>${basedir}/../../</doris.home>
        <doris.thirdparty>${basedir}/../../thirdparty</doris.thirdparty>
    </properties>

只需要將這裡的 flink.version 改成和你 Flink 叢集版本一致,重新編輯即可。

4.2 配置 Flink

這裡我們是通過 Flink Sql Client 方式來進行操作。

這裡我們演示使用的軟體版本:

  1. Mysql 8.x
  2. Apache Flink :1.13.3
  3. Apache Doris :0.14.13.1

4.2.1 安裝 Flink

首先下載和安裝 Flink :

https://dlcdn.apache.org/flin...

這裡演示使用的是本地單機模式:

# wget https://dlcdn.apache.org/flink/flink-1.12.5/flink-1.12.5-bin-scala_2.12.tgz
# tar zxvf flink-1.12.5-bin-scala_2.12.tgz 

下載 Flink CDC 相關 Jar 包:

https://repo1.maven.org/maven...

這裡注意 Flink CDC 和 Flink 的版本對應關係。

image-20211025170642628

  • 將上面下載或者編譯好的 Flink Doris Connector jar 包複製到 Flink 根目錄下的 lib 目錄下;
  • Flink CDC 的 jar 包也複製到 Flink 根目錄下的 lib 目錄下。

image-20211026095513892

4.2.2 啟動 Flink

這裡我們使用的是本地單機模式。

# bin/start-cluster.sh
Starting cluster.
Starting standalonesession daemon on host doris01.
Starting taskexecutor daemon on host doris01.

我們通過 web 訪問 (預設埠是 8081) 啟動起來 Flink 叢集,可以看到叢集正常啟動。

image-20211025162831632

4.3 安裝 Apache Doris

具體安裝部署 Doris 的方法,參照下面的連線:

https://hf200012.github.io/20...環境安裝部署。

4.4 安裝配置 Mysql

  1. 安裝 Mysql,快速使用 Docker 安裝配置 Mysql,具體參照下面的連線:

    https://segmentfault.com/a/11...

  2. 開啟 Mysql binlog,進入 Docker 容器修改 /etc/my.cnf 檔案,在 [mysqld] 下面新增以下內容,

    log_bin=mysql_bin
    binlog-format=Row
    server-id=1

    然後重啟 Mysql。

    systemctl restart mysqld
  3. 建立 Mysql 資料庫表。
 CREATE TABLE `test_cdc` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
 ) ENGINE=InnoDB 

4.5 建立 Doris 表

CREATE TABLE `doris_test` (
  `id` int NULL COMMENT "",
  `name` varchar(100) NULL COMMENT ""
 ) ENGINE=OLAP
 UNIQUE KEY(`id`)
 COMMENT "OLAP"
 DISTRIBUTED BY HASH(`id`) BUCKETS 1
 PROPERTIES (
 "replication_num" = "3",
 "in_memory" = "false",
 "storage_format" = "V2"
 );

4.6 啟動 Flink Sql Client

./bin/sql-client.sh embedded
> set execution.result-mode=tableau;

image-20211025165547903

4.6.1 建立 Flink CDC Mysql 對映表

CREATE TABLE test_flink_cdc ( 
  id INT, 
  name STRING,
  primary key(id)  NOT ENFORCED
) WITH ( 
  'connector' = 'mysql-cdc', 
  'hostname' = 'localhost', 
  'port' = '3306', 
  'username' = 'root', 
  'password' = 'password', 
  'database-name' = 'demo', 
  'table-name' = 'test_cdc' 
);

執行查詢建立的 Mysql 對映表,顯示正常。

select * from test_flink_cdc;

image-20211026100505972

4.6.2 建立 Flink Doris Table 對映表

使用 Doris Flink Connector 建立 Doris 對映表。

CREATE TABLE doris_test_sink (
   id INT,
   name STRING
) 
WITH (
  'connector' = 'doris',
  'fenodes' = 'localhost:8030',
  'table.identifier' = 'db_audit.doris_test',
  'sink.batch.size' = '2',
  'sink.batch.interval'='1',
  'username' = 'root',
  'password' = ''
)

在命令列下執行上面的語句,可以看到建立表成功,然後執行查詢語句,驗證是否正常。

select * from doris_test_sink;

image-20211026100804091

執行插入操作,將 Mysql 裡的資料通過 Flink CDC 結合 Doris Flink Connector 方式插入到 Doris 中。

INSERT INTO doris_test_sink select id,name from test_flink_cdc

image-20211026101004547

提交成功之後我們在 Flink 的 Web 介面可以看到相關的 Job 任務資訊。

image-20211026100943474

4.6.3 向 Mysql 表中插入資料

INSERT INTO test_cdc VALUES (123, 'this is a update');
INSERT INTO test_cdc VALUES (1212, '測試flink CDC');
INSERT INTO test_cdc VALUES (1234, '這是測試');
INSERT INTO test_cdc VALUES (11233, 'zhangfeng_1');
INSERT INTO test_cdc VALUES (21233, 'zhangfeng_2');
INSERT INTO test_cdc VALUES (31233, 'zhangfeng_3');
INSERT INTO test_cdc VALUES (41233, 'zhangfeng_4');
INSERT INTO test_cdc VALUES (51233, 'zhangfeng_5');
INSERT INTO test_cdc VALUES (61233, 'zhangfeng_6');
INSERT INTO test_cdc VALUES (71233, 'zhangfeng_7');
INSERT INTO test_cdc VALUES (81233, 'zhangfeng_8');
INSERT INTO test_cdc VALUES (91233, 'zhangfeng_9');

4.6.4 觀察 Doris 表的資料

首先停掉 Insert into 這個任務,因為我是在本地單機模式,只有一個 task 任務,所以要停掉,然後在命令列執行查詢語句才能看到資料。

image-20211026101203629

4.6.5 修改 Mysql 的資料

重新啟動 Insert into 任務:

image-20211025182341086

修改 Mysql 表裡的資料:

update test_cdc set name='這個是驗證修改的操作' where id =123

再去觀察 Doris 表中的資料,你會發現已經修改。

注意這裡如果要想 Mysql 表裡的資料修改,Doris 裡的資料也同樣修改,Doris 資料表的模型要是 Unique key 模型,其他資料模型 (Aggregate Key 和 Duplicate Key) 不能進行資料的更新操作。

image-20211025182435827

4.6.6 刪除資料操作

目前 Doris Flink Connector 還不支援刪除操作,後面計劃會加上這個操作。

更多 Flink CDC 相關技術問題,可掃碼加入社群釘釘交流群~

img


相關文章

近期熱點

img


更多 Flink 相關技術問題,可掃碼加入社群釘釘交流群
第一時間獲取最新技術文章和社群動態,請關注公眾號~

image.png

相關文章