技術乾貨|如何利用 ChunJun 實現資料實時同步?
實時同步是 ChunJun 的⼀個重要特性,指在資料同步過程中,資料來源與⽬標系統之間的資料傳輸和更新⼏乎在同⼀時間進⾏。
在實時同步場景中我們更加關注源端,當源系統中的資料發⽣變化時,這些變化會⽴即傳輸並應⽤到⽬標系統,以保證兩個系統中的資料保持⼀致。這個特性需要作業運⾏過程中 source 外掛不間斷地頻繁訪問源端。在⽣產場景下,對於這類⻓時間運⾏、資源可預估、需要穩定性的作業,我們推薦使⽤ perjob 模式部署。
外掛⽀持 JSON 指令碼和 SQL 指令碼兩種配置⽅式,具體的引數配置請參考「ChunJun聯結器文件」:
本文將為大家介紹如何使用 ChunJun 實時同步,以及 ChunJun ⽀持的 RDB 實時採集外掛的特性、採集邏輯及其原理,幫助大家更好地理解 ChunJun 與實時同步。
如何使用 ChunJun 實時同步
為了讓⼤家能更深⼊瞭解如何使⽤ ChunJun 做實時同步,我們假設有這樣⼀個場景:⼀個電商⽹站希望將其訂單資料從 MySQL 資料庫實時同步到 HBase 資料庫,以便於後續的資料分析和處理。
在這個場景中,我們將使⽤ Kafka 作為中間訊息佇列,以實現 MySQL 和 HBase 之間的資料同步。這樣做的好處是 MySQL 表中變更可以實時同步到 HBase 結果表中,⽽不⽤擔⼼歷史資料被修改後 HBase 表未被同步。
如果在⼤家的實際應用場景中,不關⼼歷史資料是否變更(或者歷史資料根本不會變更),且業務表有⼀個遞增的主鍵,那麼可以參考本⽂之後的 JDBC-Polling 模式⼀節的內容。
· 資料來源元件的部署以及 ChunJun 的部署這⾥不做詳細描述
· 案例中的指令碼均以 SQL 指令碼為例,JSON 指令碼也能實現相同功能,但在引數名上可能存在出⼊,使⽤ JSON 的同學可以參考上文 「ChunJun 聯結器」⽂檔中的引數介紹
採集 MySQL 資料到 Kafka
● 資料準備
⾸先,我們在 Kafka 中建立⼀個名為 order_dml 的 topic,然後在 MySQL 中建立⼀個訂單表,並插⼊⼀些測試資料。建立表的 SQL 語句如下:
-- 建立⼀個名為ecommerce_db的資料庫,⽤於儲存電商⽹站的資料 CREATE DATABASE IF NOT EXISTS ecommerce_db; USE ecommerce_db; -- 建立⼀個名為orders的表,⽤於儲存訂單資訊 CREATE TABLE IF NOT EXISTS orders ( id INT AUTO_INCREMENT PRIMARY KEY, -- ⾃增主鍵 order_id VARCHAR(50) NOT NULL, -- 訂單編號,不能為空 user_id INT NOT NULL, -- ⽤戶ID,不能為空 product_id INT NOT NULL, -- 產品ID,不能為空 quantity INT NOT NULL, -- 訂購數量,不能為空 order_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -- 訂單⽇期,預設值為當前時間 戳,不能為空 ); -- 插⼊⼀些測試資料到orders表 INSERT INTO orders (order_id, user_id, product_id, quantity) VALUES ('ORD123', 1, 101, 2), ('ORD124', 2, 102, 1), ('ORD125', 3, 103, 3), ('ORD126', 1, 104, 1), ('ORD127', 2, 105, 5);
● 使用 Binlog 外掛採集資料到 Kafka
為了表示資料的變化型別和更好地處理資料變化,實時採集外掛一般會用 RowData(Flink 內部資料結構)中的 RowKind 記錄⽇志中的資料事件(insert、delete 等)型別,binlog 外掛也⼀樣。而當資料被打到 Kafka 中時,RowKind 資訊應該怎麼處理呢?
這⾥我們就需要⽤到 upsert-kafka-x,upsert-kafka-x 會識別 RowKind。對各類時間的處理邏輯如下:
• insert 資料:序列化後直接打⼊
• delete 資料:只寫 key,value 置為 null
• update 資料:分為⼀條 delete 資料和 insert 資料處理,即先根據主鍵刪除原本的資料,再寫⼊ update 後的資料
在下⼀步中我們再解釋如何將 Kafka 中的資料還原到 HBase 或者其他⽀持 upsert 語義的資料庫中,接下來我們來編寫 SQL 指令碼,實現 MySQL 資料實時採集到 Kafka 中的功能,示例如下:
CREATE TABLE binlog_source ( id int, order_id STRING, user_id INT, product_id int, quantity int, order_date TIMESTAMP(3) ) WITH ( 'connector' = 'binlog-x', 'username' = 'root', 'password' = 'root', 'cat' = 'insert,delete,update', 'url' = 'jdbc:mysql://localhost:3306/ecommerce_db?useSSL=false', 'host' = 'localhost', 'port' = '3306', 'table' = 'ecommerce_db.orders', 'timestamp-format.standard' = 'SQL', 'scan.parallelism' = '1' ); CREATE TABLE kafka_sink ( id int, order_id STRING, user_id INT, product_id int, quantity int, order_date TIMESTAMP(3),PRIMARY KEY (id) NOT ENFORCED ) WITH ( 'connector' = 'upsert-kafka-x', 'topic' = 'orders', 'properties.bootstrap.servers' = 'localhost:9092', 'key.format' = 'json', 'value.format' = 'json', 'value.fields-include' = 'ALL', 'sink.parallelism' = '1' ); insert into kafka_sink select * from binlog_source u;
還原 Kafka 中的資料到 HBase
上述步驟中,我們透過 binlog-x 和 upsert-kafka-x,將 MySQL 中的資料實時採集到了 Kafka 中。解鈴還須系鈴⼈,我們可以透過 upsert-kafka-x 再去將 Kafka 中的資料解析成帶有 upsert 語義的資料。
upsert-kafka-x 作為 source 外掛時,會判斷 Kafka 中資料的 value 是否為 null,如果 value 為 null 則標記這條資料的 RowKind 為 DELETE,否則將資料的 ROWKIND 標記為 INSERT。
ChunJun的 hbase-x 外掛⽬前已經具備了 upsert 語句的能⼒,使⽤ hbase-x 即可將 Kafka 中的資料還原到 hbase中。接下來是 SQL 指令碼示例,為了⽅便在 HBase 中檢視資料結果,我們將 int 資料 cast 為 string 型別:
CREATE TABLE kafka_source ( id int, order_id STRING, user_id INT, product_id INT, quantity INT, order_date TIMESTAMP(3), PRIMARY KEY (id) NOT ENFORCED ) WITH ( 'connector' = 'upsert-kafka-x', 'topic' = 'orders', 'properties.bootstrap.servers' = 'localhost:9092', 'properties.group.id' = 'test_group', 'key.format' = 'json', 'value.format' = 'json', 'scan.parallelism' = '1' ); CREATE TABLE hbase_sink( rowkey STRING, order_info ROW < order_id STRING, user_id STRING, product_id STRING, quantity STRING, order_date STRING >, PRIMARY KEY (rowkey) NOT ENFORCED ) WITH( -- 這⾥以hbase14為例,如果hbase版本是2.x,我們可以使⽤hbase2-x外掛代替 'connector' = 'hbase14-x', 'zookeeper.quorum' = 'localhost:2181', 'zookeeper.znode.parent' = '/hbase', 'table-name' = 'ecommerce_db:orders', 'sink.parallelism' = '1' ); INSERT INTO hbase_sink SELECT cast(id as STRING), ROW( cast(order_id as STRING), cast(user_id as STRING), cast(product_id as STRING), cast(quantity as STRING), cast(order_date as STRING) ) FROM kafka_source
Tips:如果我們不需要 Kafka 中介軟體,也可以使⽤ binlog-x 外掛直接對接 hbase-x 外掛。
ChunJun 支援的 RDB 實時採集外掛
本節主要介紹 ChunJun 的 RDB 實時採集外掛的特性、採集邏輯及其原理。
ChunJun 的 RDB 實時採集可以實時監視資料庫中的更改,並在發⽣更改時讀取資料變化,例如插⼊、更新和刪除操作。使⽤ ChunJun 實時採集,我們可以實時獲取有關資料庫中更改的資訊,從⽽能夠及時響應這些更改,如此便可以幫助我們更好地管理和利⽤ RDB 資料庫中的資料。
並且 ChunJun 提供了故障恢復和斷點續傳功能來確保資料的完整性。ChunJun 實時採集類外掛的⼤致實現步驟如下:
· 連線資料庫,確認讀取點位,讀取點位可以理解為⼀個 offset,如 Binlog 中,指⽇志的⽂件名和⽂件的 position 資訊
· 根據讀取點位開始讀取 redolog,獲取其中關於資料變更相關的操作記錄
· 根據 tableName、操作事件(如insert、delete、update)等過濾資訊過濾出需要的 log ⽇志
· 解析 log ⽇志,解析後的事件資訊包括表名、資料庫名、操作型別(插⼊、更新或刪除)和變更的資料⾏等
· 將解析出來的資料會加⼯為 ChunJun 內部統⼀的 DdlRowData 供下游使⽤
ChunJun ⽬前已⽀持的實時採集 Connector 有:binlog(mysql)、oceanbasecdc、oraclelogminer、sqlservercdc。
Binlog 簡介
ChunJun binlog 外掛的主要功能是讀取 MySQL 的⼆進位制⽇志(binlog)⽂件。這些⽂件記錄了所有對資料的更改操作,如插⼊、更新和刪除等。⽬前,該外掛依賴 Canal 元件來讀取 MySQL 的 binlog ⽂件。
核⼼操作步驟如下:
• 確認讀取點位:在 binlog 外掛中,我們可以在指令碼的 start 欄位中直接指定 journal-name(binlog ⽂件名)和 position(⽂件的特定位置)
• 讀取binlog:binlog 外掛將⾃身偽裝成 MySQL 的 Slave 節點,向 MySQL Master 傳送請求,要求將 binlog ⽂件的資料流傳送給它
• 故障恢復和斷點續傳:故障時,外掛會記錄當前的 binlog 位置資訊,從 checkpoint/savepoint 恢復後,我們可以從上次記錄的位置繼續讀取 binlog ⽂件,確保資料變化的完整性
使⽤ binlog 所需的許可權在「binlog外掛使⽤⽂檔」中有詳細說明,連結如下:
OracleLogminer 簡介
Logminer 外掛藉助 Oracle 提供的 Logminer ⼯具透過讀取檢視的⽅式獲取 Oracle redolog 中的資訊。
核⼼操作步驟如下:
01 定位需讀取起始點位(start_scn)
⽬前 logminer ⽀持四種策略指定 StartScn:
· all:從 Oracle 資料庫中最早的歸檔⽇志組開始採集(不建議使⽤)
· current:任務運⾏時的 SCN 號
· time:指定時間點對應的 SCN 號
· scn:直接指定 SCN 號
02 定位需要讀取的結束點位(end_scn)
外掛根據 start_scn 和 maxLogFileSize(預設5G)獲取可載入的 redolog ⽂件列表,end_scn 取這個⽂件列表中最⼤的 scn 值。
03 載入 redo ⽇志到 Logminer
透過⼀個儲存過程,將 scn 區間範圍內的 redolog 載入到 Logminer ⾥。
04 從檢視中讀取資料
以 scn > ? 作為 where 條件直接查詢 v$logmnr_contents 檢視內的資訊即可獲取 redolog 中的資料。
05 重複1-4步驟,實現不斷的讀取
如標題。
06 故障恢復和斷點續傳
在發⽣故障時,外掛會儲存當前消費的 scn 號,重啟時從上次的 scn 號開始讀取,確保資料完整性。
• 關於該外掛原理的詳細介紹請參⻅「Oracle Logminer 實現原理說明⽂檔」:
• 使⽤lominer外掛的前提條件詳⻅「Oracle配置LogMiner」:
SqlServerCDC 簡介
SqlServerCDC 外掛依賴 SQL Server 的 CDC Agent 服務提供的檢視獲取 redolog 中的資訊。
核⼼操作步驟如下:
01 定位需讀取起始點位(from_lsn)
⽬前 SqlserverCDC 僅⽀持直接配置 lsn 號,如果 lsn 號未配置,則取資料庫中當前最⼤的 lsn 號為 from_lsn。
02 定位需要讀取的結束點位(to_lsn)
SqlserverCDC 外掛定期地(可透過 pollInterval 引數指定)獲取資料庫中的最⼤ lsn 為 end_lsn。
03 從檢視中讀取資料
查詢 Agent 服務提供的檢視中 lsn 區間範圍內的資料,過濾出需要監聽的表及事件型別。
04 重複1-3步驟,實現不斷的讀取
如標題。
05 故障恢復和斷點續傳
在發⽣故障時,外掛會儲存當前消費的 lsn 號。重啟時從上次的 lsn 號開始讀取,確保資料完整性。
• 關於該外掛原理的詳細介紹請參⻅「Sqlserver CDC 實現原理說明⽂檔」:
• 配置 SqlServer CDC Agent 服務詳⻅「Sqlserver 配置 CDC ⽂檔」:
OceanBaseCDC 簡介
OceanBase 是螞蟻集團開源的⼀款分散式關係型資料庫,它使⽤⼆進位制⽇志(binlog)記錄資料變更。OceanBaseCDC 的實現依賴於 OceanBase 提供的 LogProxy 服務,LogProxy 提供了基於釋出-訂閱模型的服務,允許使⽤ OceanBase 的 logclient 訂閱特定的 binlog 資料流。
OceanBaseCDC 啟動⼀個 Listener 執行緒。當 logclient 連線到 LogProxy 後,Listener 會訂閱經過資料過濾的 binlog,然後將其新增到內部維護的列表中。當收到 COMMIT 資訊後,Listener 會將⽇志變更資訊傳遞給⼀個阻塞佇列,由主執行緒消費並將其轉換為 ChunJun 內部的 DdlRowData,最終傳送到下游。
JDBC-Polling 模式讀
JDBC 外掛的 polling 讀取模式是基於 SQL 語句做資料讀取的,相對於基於重做⽇志的實時採整合本更低,但 jdbc 外掛做實時同步對業務場景有更⾼的要求:
· 有⼀個數值型別或者時間型別的遞增主鍵
· 不更新歷史資料或者不關⼼歷史資料是否更新,僅關⼼新資料的獲取
實現原理簡介
• 設定遞增的業務主鍵作為 polling 模式依賴的增量鍵
• 在增量讀取的過程中,實時記錄 increColumn 對應的值(state),作為下⼀次資料讀取的起始點位
• 當⼀批資料讀取完後,間隔⼀段時間之後依據 state 讀取下⼀批資料
polling 依賴部分增量同步的邏輯,關於增量同步的更多介紹可以點選:
如何配置⼀個 jdbc-polling 作業
先介紹⼀下開啟 polling 模式需要關注的配置項:
以 MySQL 為例,假設我們有⼀個儲存訂單資訊的歷史表,且訂單的 order_id 是遞增的,我們希望定期地獲取這張表的新增資料。
CREATE TABLE order.realtime_order_archive ( order_id INT PRIMARY KEY COMMENT '訂單唯⼀標識', customer_id INT COMMENT '客戶唯⼀標識', product_id INT COMMENT '產品唯⼀標識', order_date TIMESTAMP COMMENT '訂單⽇期和時間', payment_method VARCHAR(255) COMMENT '⽀付⽅式(信⽤卡、⽀付寶、微信⽀付等)', shipping_method VARCHAR(255) COMMENT '配送⽅式(順豐速運、圓通速遞等)', shipping_address VARCHAR(255) COMMENT '配送地址', order_total DECIMAL(10,2) COMMENT '訂單總⾦額', discount DECIMAL(10,2) COMMENT '折扣⾦額', order_status VARCHAR(255) COMMENT '訂單狀態(已完成、已取消等)' );
我們可以這樣配置 json 指令碼的 reader 資訊。
"name": "mysqlreader", "parameter": { "column" : [ "*" //這⾥假設我們讀取所有欄位,可以填寫‘*’ ], "increColumn": "id", "polling": true, "pollingInterval": 3000, "username": "username", "password": "password", "connection": [ { "jdbcUrl": [ "jdbc:mysql://ip:3306/liuliu?useSSL=false" ], "schema":"order", "table": [ "realtime_order_archive" ] } ] } }
《資料治理行業實踐白皮書》下載地址:
《數棧產品白皮書》免費獲取:
想了解更多有關袋鼠雲大資料產品、行業解決方案、客戶案例的朋友,瀏覽袋鼠雲官網:https://www.dtstack.com/?src=szitpub
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69995740/viewspace-2948356/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 技術乾貨|如何利用 ChunJun 實現資料離線同步?
- 技術乾貨|如何實現分鐘級故障管理
- 技術乾貨 | 資料中介軟體如何與GreatSQL資料同步?SQL
- SSLO如何實現會話保持?技術乾貨線上分享會話
- DTCC 乾貨 | 中國銀聯跨中心,異構資料同步技術與實踐
- Oracle實時同步技術Oracle
- 乾貨|淺談iOS端短影片SDK技術實現iOS
- 淘寶/天貓商品詳情實時資料API技術實現API
- 技術乾貨 | 解鎖Redis 時間序列資料的應用Redis
- 技術乾貨|品高雲的SDN實踐
- 技術乾貨| MongoDB時間序列集合MongoDB
- 如何設計實時資料平臺(技術篇)
- mysql和redis實時同步資料怎麼實現MySqlRedis
- 技術乾貨收集
- 乾貨 | 京東技術中臺的Flutter實踐之路Flutter
- Kafka 叢集如何實現資料同步?Kafka
- Mysql資料實時同步實踐MySql
- 技術乾貨 | 利用systemd管理MySQL單機多例項MySql
- 乾貨 | 影像資料增強實戰
- 【技術乾貨】Oracle資料庫漏洞掃描指南Oracle資料庫
- 【教程乾貨】HTML5技術資料大共享HTML
- TiDB 作為 MySQL Slave 實現實時資料同步TiDBMySql
- 資料同步:教你如何實時把資料從 MySQL 同步到 OceanBaseMySql
- PLC實時資料採集如何實現?
- 【實驗】利用可傳輸表空間技術實現資料的高效遷移
- 技術乾貨 | Flutter線上程式設計實踐總結Flutter程式設計
- 技術解讀資料庫如何實現“多租戶”?資料庫
- 什麼是資料實時同步,為什麼資料實時同步很重要
- 利用python實現mysql資料庫向sqlserver的同步PythonMySql資料庫Server
- 利用DB Link實現資料庫間的表同步資料庫
- 資料視覺化實用乾貨分享視覺化
- 資料加密新技術-實時雲渲染技術應用加密
- Linux下Rsync+Inotify-tools實現資料實時同步Linux
- Cocos 技術派:實時競技小遊戲技術實現分享遊戲
- 聊聊如何利用redis實現多級快取同步Redis快取
- oracle同步軟體技術實現對比Oracle
- 開源技術交流丨批流一體資料同步引擎 ChunJun 資料還原 - DDL 功能模組解析
- 如何利用Redis實現延時處理Redis