全量同步 Elasticsearch 方案之 Canal

小程式開發發表於2022-07-13

Canal 是阿里的一款開源專案,純  Java 開發。基於資料庫增量日誌解析,提供增量資料訂閱 & 消費,目前主要支援了  MySQL(也支援  mariaDB)。

file

Canal 除了支援  binlog 實時  增量同步 資料庫之外也支援  全量同步 ,本文主要分享使用 Canal 來實現從 MySQL 到 Elasticsearch 的全量同步;

可通過使用  adapter 的  REST 介面手動觸發  ETL 任務,實現全量同步。

在執行全量同步的時候,同一個  destination 的增量同步任務會被  阻塞,待全量同步完成被阻塞的增量同步會被  重新喚醒

二、ETL 介面

adapter 的  ETL 介面為: /etl/{type}/{task}

  • 預設 web 埠為  8081
  • type 為型別 (hbase/es7/rdb)
  • task 為任務名對應配置檔名,如 sys_user.yml

 

例子

curl -X POST 

執行成功輸出:

{"succeeded":true,"resultMessage":"匯入ES 資料:17 條"}

 

三、實踐過程中遇到的坑

3.1. 連線池不夠

當同步的資料量比較大時,執行一段時間後會出現下圖的錯誤  file

3.1.1. 原因分析

檢視  canal 原始碼得知當同步的資料量大於 1w 時,會分批進行同步,每批 1w 條記錄,並使用多執行緒來並行執行任務,而  adapter 預設的連線池為 3,當執行緒獲取資料庫連線等待超過 1 分鐘就會丟擲該異常。

執行緒數為當前伺服器 cpu 的可用執行緒數

 

3.1.2. 解決方式

修改  adapter 的  conf/application.yml 檔案中的  srcDataSources 配置項,增加  maxActive 配置資料庫的最大連線數為當前伺服器 cpu 的可用執行緒數

cpu 執行緒數可以下命令檢視

grep 'processor' /proc/cpuinfo | sort -u | wc -l

 

3.2. es 連線超時

當同步的表欄位比較多時,機率出現以下報錯  mark

3.2.1. 原因分析

由於  adapter 的表對映配置檔案中的  commitBatch 提交批大小設定過大導致 (6000)

 

3.2.2. 解決方式

修改  adapter 的  conf/es7/xxx.yml 對映檔案中的  commitBatch 配置項為 3000

 

3.3. 同步慢

三千萬的資料量用時 3.5 小時左右

3.3.1. 原因分析

file

由於當資料量大於 1w 時  canal 會對資料進行分批同步,每批 1w 條通過分頁查詢實現;所以當資料量較大時會出現深分頁的情況導致查詢非常慢。

 

3.3.2. 解決方式

預先使用 ID、時間或者業務欄位等進行資料分批後再進行同步,減少每次同步的資料量。

 

3.3.3. 案例

使用 ID 進行資料分批,適合增長型別的 ID,如自增 ID、雪花 ID 等;

  1. 查出  最小 ID最大 ID 與  總資料量
  2. 根據每批資料量大小計算每批的  ID 區間

 

計算過程

  • 最小 ID = 1333224842416979257
  • 最大 ID = 1341698897306914816
  • 總資料量 = 3kw
  • 每次同步量 = 300w

 

(1) 計算同步的次數

總資料量 / 每次同步量 = 10

 

(2) 計算每批 ID 的增量值

(最大ID - 最小ID) / 次數 = 847405488993555.9

 

(3) 計算每批 ID 的值

最小ID + 增量值 = ID2ID2 + 增量值 = ID3...ID9 + 增量值 = 最大ID

 

(4) 使用分批的 ID 值進行同步

修改 sql 對映配置,的  etlCondition 引數:

etlCondition: "where id >= {} and id < {}"

 

呼叫 etl 介面,並增加  params 引數,多個引數之間使用  ; 分割

curl -X POST ?params=最小ID;ID2curl -X POST ?params=ID2;ID3...

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70019616/viewspace-2905622/,如需轉載,請註明出處,否則將追究法律責任。

相關文章