數據同步的方式
數據同步的2大方式
- 基於SQL查詢的 CDC(Change Data Capture):
- 離線調度查詢作業,批處理。把一張表同步到其他系統,每次通過查詢去獲取表中最新的數據。也就是我們說的基於SQL查詢抽取;
- 無法保障數據一致性,查的過程中有可能數據已經發生了多次變更;
- 不保障實時性,基於離線調度存在天然的延遲;
- 工具軟件以Kettle(Apache Hop最新版)、DataX爲代表,需要結合任務調度系統使用。
- 基於日誌的 CDC:
- 實時消費日誌,流處理,例如 MySQL 的 binlog 日誌完整記錄了數據庫中的變更,可以把 binlog 文件當作流的數據源;
- 保障數據一致性,因爲 binlog 文件包含了所有歷史變更明細;
- 保障實時性,因爲類似 binlog 的日誌文件是可以流式消費的,提供的是實時數據;
- 工具軟件以Flink CDC、阿里巴巴Canal、Debezium爲代表。
基於SQL查詢增量數據同步原理
我們考慮用SQL如何查詢增量數據? 數據有增加、修改、刪除 刪除數據採用邏輯刪除的方式,比如定義一個is_deleted字段標識邏輯刪除 如果數據是 UPDATE的,也就是會被修改的,那麼 where update_datetime >= last_datetime(調度滾動時間)就是增量數據 如果數據是 APPEND ONLY 的除了用更新時間還可以用where id >= 調度上次last_id
結合任務調度系統 調度時間是每日調度執行一次,那麼 last_datetime = 當前調度開始執行時間 - 24小時,延遲就是1天 調度時間是15分鐘一次,那麼 last_datetime = 當前調度開始執行時間 - 15分鐘,延遲就是15分鐘
這樣就實現了捕獲增量數據,從而實現增量同步
DolphinScheduler + Datax 構建離線增量數據同步平臺
本實踐使用 單機8c16g DataX 2022-03-01 官網下載 DolphinScheduler 2.0.3(DolphinScheduler的安裝過程略,請參考官網)
DolphinScheduler 中設置好DataX環境變量 DolphinScheduler 提供了可視化的作業流程定義,用來離線定時調度DataX Job作業,使用起來很是順滑
基於SQL查詢離線數據同步的用武之地 爲什麼不用基於日誌實時的方式?不是不用,而是根據場合用。考慮到業務實際需求情況,基於SQL查詢這種離線的方式也並非完全淘汰了 特別是業務上實時性要求不高,每次調度增量數據沒那麼大的情況下,不需要分佈式架構來負載,這種情況下是比較合適的選擇 場景舉例: 網站、APP的百萬級、千萬級的內容搜索,每天幾百篇內容新增+修改,搜索上會用到ES(ElasticSearch),那麼就需要把 MySQL內容數據增量同步到ES DataX就能滿足需求!
DolphinScheduler中配置DataX MySQL To ElasticSearch工作流
工作流定義
工作流定義 > 創建工作流 > 拖入1個SHELL組件 > 拖入1個DATAX組件 SHELL組件(文章) 腳本
echo '文章同步 MySQL To ElasticSearch'
DATAX組件(t_article) 用到2個插件mysqlreader、elasticsearchwriter^[1] 選 自定義模板:
{
"job": {
"content": [
{
"reader": {
"name": "mysqlreader",
"parameter": {
"connection": [
{
"jdbcUrl": [
"jdbc:mysql://${biz_mysql_host}:${biz_mysql_port}/你的數據庫?useUnicode=true&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF8&autoReconnect=true&useSSL=false&&allowLoadLocalInfile=false&autoDeserialize=false&allowLocalInfile=false&allowUrlInLocalInfile=false"
],
"querySql": [
"select a.id as pk,a.id,a.title,a.content,a.is_delete,a.delete_date,a.create_date,a.update_date from t_article a.update_date >= '${biz_update_dt}';"
]
}
],
"password": "${biz_mysql_password}",
"username": "${biz_mysql_username}"
}
},
"writer": {
"name": "elasticsearchwriter",
"parameter": {
"endpoint": "${biz_es_host}",
"accessId": "${biz_es_username}",
"accessKey": "${biz_es_password}",
"index": "t_article",
"type": "_doc",
"batchSize": 1000,
"cleanup": false,
"discovery": false,
"dynamic": true,
"settings": {
"index": {
"number_of_replicas": 0,
"number_of_shards": 1
}
},
"splitter": ",",
"column": [
{
"name": "pk",
"type": "id"
},
{
"name": "id",
"type": "long"
},
{
"name": "title",
"type": "text"
},
{
"name": "content",
"type": "text"
}
{
"name": "is_delete",
"type": "text"
},
{
"name": "delete_date",
"type": "date"
},
{
"name": "create_date",
"type": "date"
},
{
"name": "update_date",
"type": "date"
}
]
}
}
}
],
"setting": {
"errorLimit": {
"percentage": 0,
"record": 0
},
"speed": {
"channel": 1,
"record": 1000
}
}
}
}
reader和writer的字段配置需保持一致
自定義參數:
biz_update_dt: ${global_bizdate}
biz_mysql_host: 你的mysql ip
biz_mysql_port: 3306
biz_mysql_username: 你的mysql賬號
biz_mysql_password: 你的mysql密碼
biz_es_host: 你的es地址帶協議和端口 http://127.0.0.1:9200
biz_es_username: 你的es賬號
biz_es_password: 你的es密碼
配置的自定義參數將會自動替換json模板中的同名變量
reader mysqlreader插件中關鍵配置: a.update_date >= '${biz_update_dt}'
就是實現增量同步的關鍵配置 writer elasticsearchwriter插件中關鍵配置: ``
"column": [
{
"name": "pk",
"type": "id"
},
......
]
type = id 這樣配置,就把文章主鍵映射到es主鍵 _id
從而實現相同主鍵id重複寫入數據,就會更新數據。如果不這樣配置數據將會重複導入es中
保存工作流
全局變量設置 global_bizdate: $[yyyy-MM-dd 00:00:00-1]
global_bizdate 引用的變量爲 DolphinScheduler 內置變量,具體參考官網文檔^[2] 結合調度時間設計好時間滾動的窗口時長,比如按1天增量,那麼這裏時間就是減1天
最終的工作流DAG圖爲:
by 流水理魚|wwek
參考
1. DataX ElasticSearchWriter 插件文檔 2. Apache DolphinScheduler 內置參數 本文首發於流水理魚博客,如要轉載請註明出處。 歡迎關注我的公衆號:流水理魚(liushuiliyu),全棧、雲原生、Homelab交流。 如果您對相關文章感興趣,也可以關注我的博客:www.iamle.com 上面有更多內容