從 SQL Server 到 MySQL (三):愚公移山 – 開源力量

alswl發表於2019-03-04
201806/refactor.png

我們用了兩章文章
從 SQL Server 到 MySQL(一):異構資料庫遷移
/
從 SQL Server 到 MySQL(二):線上遷移,空中換髮動機
介紹我們遇到問題和解決方案。
不管是離線全量遷移還是線上無縫遷移,
核心 ETL 工具就是 yugong。

Yugong 是一個成熟工具, 在阿里巴巴去 IOE 行動中起了重要作用,
它與 Otter / Canal 都是阿里中介軟體團隊出品。
它們三者各有分工:
Yugong 設計目標是異構資料庫遷移;
Canal 設計用來解決 MySQL binlog 訂閱和消費問題;
Otter 則是在 Canal 之上,以準實時標準解決資料庫同步問題。
Otter 配備了相對 yugong 更健壯管理工具、分散式協調工具,
從而長期穩定執行。Yugong 設計目標則是一次性遷移工作,偏 Job 型別。
當然 yugong 本身質量不錯,長期執行也沒問題。
我們有個產線小夥伴使用我們魔改後 yugong,
用來將資料從管理平臺同步資料到使用者前臺,已經穩定跑了半年多了。

yugong 系統結構

這裡我不贅述如何使用 yugong,有需求同學直接去
官方文件 檢視使用文件。

我直接進入關鍵環節:解剖 yugong 核心模組。
Yugong 資料流是標準 ETL 流程,分別有 Extractor / Translator / Applier
這三個大類來實現 ETL 過程:

ETL & Java Class

我們依次來看看這三大類具體設計。

Extractor

Extractor Class
  • YuGongLifeCycle:Yugong 元件生命週期宣告
  • AbstractYuGongLifeCycle:Yugong 元件生命週期一些實現
  • RecordExtractor:基礎 Extractor Interface
  • AbstractRecordExtractor:基礎 Extractor 虛擬類,做了一部分實現
  • AbstractOracleRecordExtractor:Oracle Extractor 虛擬類,做了一部分 Oracle 相關實現
  • OracleOnceFullRecordExtractor:Oracle 基於特定 SQL 一次性 Extractor
  • OracleFullRecordExtractor:Oracle 全量 Extractor
  • OracleRecRecordExtractor:Oracle 記錄 Extractor,用來建立物化檢視
  • OracleMaterializedIncRecordExtractor:基於(已有)物化檢視 Oracle 增量 Extrator
  • OracleAllRecordExtractor:Oracle 自動化 Extractor,先 Mark 再 Full,再 Inc

Exctractor 從 Source DB 讀取資料寫入記憶體,
Yugong 官方提供 Extractor 抽象出 AbstractRecordExtractor 類,
其餘類都是圍繞 Oracle 實現。
另外 Yugong 設計了 YuGongLifeCycle 類實現了元件生命週期管理。

Translator

Translator Class
  • DataTranslator:Translator 基類,為 Row 級別資料處理
  • TableTranslator:Translator 基類,為 Table 級別提供處理(官方程式碼中沒有使用)
  • AbstractDataTranslator:Data Translator 虛擬類,做了部分實現
  • EncodeDataTranslator:轉換編碼格式 Translator
  • OracleIncreamentDataTranslator:為 Oracle 增量資料準備 Translator,會調整一些資料狀態
  • BackTableDataTranslator:Demo,允許在 Translator 中做回寫資料操作
  • BillOutDataTranslator:Demo,包含一些阿里業務邏輯 Translator
  • MidBillOutDetailDataTranslator:Demo,包含一些阿里業務邏輯 Translator

Translator 讀取記憶體中 RowData 然後變換,
大部分 Translator 做一些無狀態操作,比如編碼轉換。
另外還有一小部分 Translator 做了業務邏輯操作,比如做一些資料回寫。

Applier

Applier Class
  • RecordApplier:基礎 Applier Interface
  • AbstractRecordApplier:基礎 Applier 虛擬類,做了一部分實現
  • CheckRecordRecordApplier:檢查資料一致性 Applier,不做資料寫入
  • FullRecordRecordApplier:全量資料 Applier,使用 UPSERT 做資料更新
  • IncreamentRecordApplier:增量 Applier,使用 Oracle 物化檢視為資料來源
  • AllRecordRecordApplier:自動化 Applier,先使用全量資料 Applier,然後使用增量資料 Applier

Applier 將經過 Translator 處理過的資料寫入 Target DB。
Yugong 提供了一致性檢查、全量、增量 Applier。
比較特殊是 AllRecordRecordApplier 提供了全套自動化操作。

Others

除了 ETL 三個要素,yugong 還有一些重要類:控制類和工具類。

  • SqlTemplate:提供 CRUD / UPSERT 等操作的基類 SQL 模板
  • OracleSqlTemplate:基於 SqlTemplate 實現的 Oracle SQL 模板
  • RecordDiffer:一致性檢查 differ
  • YugongController:應用控制器,控制整個應用資料流向
  • YugongInstance:控制單個遷移任務例項,一張表對應一個 YugongInstance

老戰士的問題

說 yugong 有問題會有些標題黨,畢竟它是久經考驗老戰士了。
但對我們來說,開源版本 yugong 還有一些不足:

  • 不支援 SQL Server 讀取
  • 不支援 SQL Server 寫入(Rollback 需要寫入 SQL Server)
  • 不支援 MySQL 讀取

除了資料庫支援,Yugong 在工程上面倒是也有一些改善空間。
我們最後花費了不少時間,做了工程上改進。

  • 拋棄預設打包方式(基於 maven-assembly-plugin 生成類似 LFS 結構 tar.gz 檔案),
    改為使用 fat jar 模式打包,僅生成單檔案可執行 jar 包
  • 拋棄 ini 配置檔案,使用 YAML 配置檔案格式(已有老配置仍然使用 ini 檔案,YAML 主要管理表結構變更)
  • 改造 Plugin 模式,將 Java 執行時編譯改為反射獲取 Java 類
  • 拆分 Unit Test / Integration Test,降低重構成本
  • 重構 Oracle 繼承結構,使其開放 SQL Server / MySQL 介面
  • 支援 Canal Redis 格式資料作為 MySQL 線上增量資料來源

改造之後結構

Extractor

Extractor New Class
  • AbstractSqlServerExtractor:新增抽象 SqlServer Extractor
  • AbstractMysqlExtractor:新增抽象 MySQL Extractor
  • AbstractFullRecordExtractor:新增抽象 Full 模式 Extractor
  • SqlServerCdcExtractor:新增 SQL Server CDC 增量模式 Extractor
  • MysqlCanalExtractor:新增 MySQL Canal 格式增量消費 Extractor
  • MysqlCanalRedisExtractor:新增 MySQL Canal 格式增量消費 Extractor,使用 Redis 做回溯
  • MysqlFullExtractor:新增 MySQL 全量 Extractor
  • SqlServerFullExtractor:新增 SQL Server 全量 Extractor

在抽象出三個抽象類之後,整體邏輯更為清晰,如果未來要增加新資料庫格式支援,也更為簡單。

Translator

Translator New Class
  • Sha1ShardingTranslator:根據 Sha1 Sharding Translator
  • ModShardingTranslator:根據 Value Mode Sharding Translator
  • RangeShardingTranslator:根據範圍 Sharding Translator
  • UserRouterMapShardingTranslator:特定業務使用, 使用者分表 Sharding Translator
  • UserRouterMapMobileShardingTranslator:特定業務使用, 使用者分表 Sharding Translator
  • ClassLearningNoteInfoShardingTranslator:特定業務使用自定義 Translator
  • ClassLearningIsActiveReverseShardingTranslator:特定業務使用自定義 Translator
  • ColumnFixDataTranslator:調整表結構 Translator
  • NameStyleDataTranslator:調整表欄位名 Translator,支援按風格對整個表自動轉換
  • CompositeIndexesDataTranslator:解決複合主鍵下唯一 PK 確定問題的 Translator

新增了一系列 Translator。

Applier

Applier New Class
  • SqlServerIncreamentRecordApplier:新增 SQL Server 增量消費 Applier

Applier 結構調整挺小,主要是增加了 SQL Server 的支援。

二次開發心得

如何快速瞭解一個開源專案?很多同學第一反應就是閱讀原始碼。
看原始碼固然是有效果,但是價效比太低。
如果專案設計不合理,很快會迷失在程式碼細節之中。
我的經驗是先閱讀官方出品的一些 Slide 分享,然後閱讀官方核心文件。
Slide 含金量高,在講述核心中核心。

如果真要去了解細節去閱讀原始碼,那我建議要善用工具,
比如使用 IntelliJ 的 Diagram 功能,抽象出核心類。
還有一些外掛比如 SequencePluginReload 方便地生成函式之間呼叫,實為檢視資料流利器。
我在這次開發過程中,也根據生成類圖發現了一些問題,
從而在進入 Coding 之前,先對框架繼承結構重構。提高了整體開發效率

根據程式碼風格判斷,Yugong 並非是出自一個人之手。這多少會導致程式碼風格和設計上面不一致。
我自己也常年在業務線裡面摸爬滾打,能想象到在快速推進專案中需要糙快猛。
但後人接受開發,多少會有些頭疼。
於是我在進入開發之前,引入標準化 CheckStyle,用 Google Style 全域性格式化,
使用 Sonar 掃描保證一個程式碼質量基線。
同時這也是一把雙刃劍,格式化專案會導致大量 diff,
這也給我自己埋下了一個苦果,在後期給上游提交 PR 引入無盡問題。

開發過程中我也犯了一些錯誤。最為頭疼是沒有在早期考慮到向開源社群貢獻,
導致未來向上遊合併困難重重,現在還在頭疼合併程式碼中。
另外,由於整體專案時間緊,我貪圖實現速度,沒有做更詳盡單元測試覆蓋。
這裡沒有遵循開源軟體的最佳實踐。

經過我改造的 Yugong 版本開源地址是:https://github.com/alswl/yugong 。
我也提交了 Pull Request https://github.com/alibaba/yugong/pull/66 ,
正在與官方溝通如何將這部分提交併入上游。


原文連結: 從 SQL Server 到 MySQL (三):愚公移山 – 開源力量 – Log4D

歡迎關注我的微信公眾號:窺豹

窺豹
如果對你有幫助,給作者 ¥2 買張彩票吧。

3a1ff193cee606bd1e2ea554a16353ee

相關文章