SeaTunnel聯結器V1到V2的架構演進與探究

語言: CN / TW / HK

核心概念

整個SeaTunnel設計的核心是利用設計模式中的控制翻轉或者叫依賴注入,主要概括為以下兩點:

  1. 上層不依賴底層,兩者都依賴抽象
  2. 流程程式碼與業務邏輯應該分離

對於整個資料處理過程,大致可以分為以下幾個流程:輸入 -> 轉換 -> 輸出,對於更復雜的資料處理,實質上也是這幾種行為的組合:

image-20220923112539846

image-20220923112619933

核心原理

SeaTunnel將資料處理的各種行為抽象成Plugin,並使用SPI技術進行動態註冊,設計思路保證了框架的靈活擴充套件,在以上理論基礎上,資料的轉換與處理還需要做統一的抽象,譬如比較有名異構資料來源同步工具DataX,也同樣對資料單條記錄做了統一抽象。

在SeaTunnel V1架構體系中,由於背靠Spark和Flink兩大分散式計算框架,框架已經為我們做好了資料來源抽象的工作,Flink的DataStream、Spark的DataFrame已經是對接入資料來源的高度抽象,在此基礎上我們只需要在外掛中處理這些資料抽象即可,同時藉助於Flink和Spark提供的SQL介面,還可以將每一次處理完的資料註冊成表,方便用SQL進行處理,減少程式碼的開發量。

實際上SeaTunnel最後的目的是自動生成一個Spark或者一個Flink作業,並提交到叢集中執行。

SeaTunnel聯結器V1 API解析

架構概覽

目前在專案dev分支下,SeaTunnel聯結器V1 API所在的模組如圖所示:

image-20220923112935210

  • seatunnel-api-base:基礎API層抽象
  • seatunnel-api-flink:Flink引擎API層抽象
  • seatunnel-api-spark:Spark引擎API層抽象

seatunnel-api-base

在基礎模組中,有以下程式碼:

image-20220923113143002

為了更清晰的理解這些類之間的關係,筆者這裡製作了一張簡單的UML類圖:

image-20220923113832778

整個API的組成可以大體分為三部分:

  1. 外掛層:提供Source、Transform、Sink外掛定義
  2. 執行層:提供執行器和執行上下文定義
  3. 構建層:提供命令列介面定義

構建層接收命令引數構建執行器,執行器初始化上下文,上下文註冊外掛並啟動外掛,至此,整個作業開始執行。

seatunnel-api-spark

在Spark引擎API層有以下程式碼:

image-20220923114642370

同樣,筆者也整理了一張UML類圖來表示它們之間的關係:

image-20220923114718982

整個流程與Base模組一致,在這裡筆者不過多贅述,有興趣的讀者可以自行觀看原始碼。

seatunnel-api-flink

在Flink引擎API層有以下程式碼:

image-20220923114843321

同樣,筆者也整理了一張UML類圖來表示它們之間的關係:

image-20220923114859270

整個流程與Base模組一致,在這裡筆者不過多贅述,有興趣的讀者可以自行觀看原始碼。

SeaTunnel聯結器V1執行原理

啟動器模組概覽

整個專案的最外層的啟動類都放在以下模組中:

image-20220923115050729

跟聯結器V1有關的模組如下:

  • seatunnel-core-base:V1基礎啟動模組
  • seatunnel-core-flink:V1flink引擎啟動模組
  • seatunnel-core-flink-sql:V1flink-sql引擎啟動模組
  • seatunnel-core-spark:V1spark引擎啟動模組

執行流程

為了更好的理解SeaTunnel V1的啟動流程,筆者在這裡製作了一張簡單的時序圖:

image-20220923115308792

程式最外層的啟動由start-seatunnel-${engine}.sh開始,使用者根據將配置檔案從指令碼傳入,指令碼呼叫org.apache.seatunnel.core.spark.SparkStarter或者org.apache.seatunnel.core.flink.FlinkStarter,實際上這個類只做一個工作:將所有引數拼接成spark-submit或者flink命令,而後指令碼接收到spark-submit或者flink命令並提交到叢集中;提交到叢集中真正執行job的類實際上是org.apache.seatunnel.spark.SeatunnelSpark或是org.apache.seatunnel.flink.SeatunnelFlink,讀者如果想直接深入瞭解作業啟動核心流程的話推薦閱讀這兩個類的原始碼。

執行原理

Spark

  1. SparkSource外掛將異構資料來源接入為DataFrame
  2. SparkTransform外掛將SparkSource接入的DataFrame進行轉換處理
  3. SparkSink外掛將SparkTransform處理好的DataFrame寫入到目標資料來源

Flink

  1. FlinkSource外掛將異構資料來源接入為DataStream
  2. FlinkTransform外掛將FlinkSource接入的DataStream進行轉換處理
  3. SparkSink外掛將FlinkTransform處理好的DataStream寫入目標資料來源

SeaTunnel聯結器V2 API解析

架構概覽

目前在專案dev分支下,SeaTunnel聯結器V2 API所在的模組如圖所示:

image-20220923234018879

  • seatunnel-api:聯結器V2所有的API定義

資料抽象

SeaTunnel聯結器V2 API在資料層面做了抽象,定義了自己的資料型別,這是與聯結器V1最大的不同點,聯結器V1使用的是引擎資料抽象的能力,但是聯結器V2自己提供的這個異構資料來源統一的能力:

image-20220923234855608

在所有的Source聯結器和Sink聯結器中,處理的都是SeaTunnelRow型別資料,同時SeaTunnel也對內設定了資料型別規範,所有通過Source接入進來的資料會被對應的聯結器轉化為SeaTunnelRow送到下游。

API Common

在API common包下有以下介面的定義:

image-20220923235045339

在這裡由於篇幅關係只介紹比較核心的幾個介面:

  • PluginIdentifierInterface:外掛唯一標識
  • SeaTunnelContext:SeaTunnel應用上下文,每個SeaTunnel Job包含的上下文物件,儲存了當前源表的元資料
  • SeaTunnelPluginLifeCycle:外掛宣告週期

具體介面中有哪些方法讀者可以自行閱讀對應類的原始碼,在這裡筆者將不過多贅述。

API Source

在API source包下有以下介面的定義:

image-20220924000305959

在這裡由於篇幅關係只介紹比較核心的幾個介面:

  • Boundedness:標識資料有界無界,聯結器V2設計理念基於批流一體,此介面用於區分流式作業還是批式作業
  • Collector:資料收集器,用於收集Source聯結器產生的資料並推往下游
  • SeaTunnelSource:Source外掛基類,所有的Source聯結器主類均繼承於這個介面
  • SourceReader:Source外掛真正處理資料接入的介面
  • SourceSplit:資料分片介面,聯結器V2支援資料並行讀入,提升資料接入效率
  • SourceSplitEnumerator:資料分片器,此介面用於分發資料分片至對應的SourceReader中

API Sink

在API sink包下有以下介面的定義:

image-20220924001119293

在這裡由於篇幅關係只介紹比較核心的幾個介面:

  • SeaTunnelSink:Sink外掛基類,所有的Sink聯結器均繼承於這個介面
  • SinkWriter:Sink外掛真正實現資料輸出的介面
  • SinkCommitter:用於處理SinkWriter#prepareCommit返回的資料資訊,包含需要提交的事務資訊,聯結器V2在Sink設計上提供二階段提交的介面,從而使聯結器有了實現Exactly-Once的可能性
  • SinkAggregatedCommitter:用於處理SinkWriter#prepareCommit返回的資料資訊,包含需要提交的事務資訊等,用於在單節點多工一起提交事務資訊,這樣可以避擴音交階段二部分失敗導致狀態不一致的問題(注:在實現聯結器時優先實現這個介面,這樣會相容性更強)

小結

image-20220924001934634

聯結器V2在架構分層上與計算引擎進行解耦,定義了自己的元資料定義以及資料型別定義,在API層和計算引擎層增加了翻譯層,將SeaTunnel自定義的資料來源通過翻譯層接入到引擎中,從而真正實現介面和引擎分離的目的。

SeaTunnel聯結器V2執行原理

啟動器模組概覽

整個專案的最外層的啟動類都放在以下模組中:

image-20220923115050729

跟聯結器V2有關的模組如下:

  • seatunnel-core-starter:V2基礎啟動模組
  • seatunnel-flink-starter:V2flink引擎啟動模組
  • seatunnel-spark-starter:V2spark引擎啟動模組

執行流程

為了更好的理解SeaTunnel V2的啟動流程,筆者在這裡製作了一張簡單的時序圖:

image-20220924004217834

程式最外層的啟動由start-seatunnel-${engine}-new-connector.sh開始,使用者根據將配置檔案從指令碼傳入,指令碼呼叫org.apache.seatunnel.core.spark.SparkStarter或者org.apache.seatunnel.core.flink.FlinkStarter,實際上這個類只做一個工作:將所有引數拼接成spark-submit或者flink命令,而後指令碼接收到spark-submit或者flink命令並提交到叢集中;提交到叢集中真正執行job的類實際上是org.apache.seatunnel.spark.SeatunnelSpark或是org.apache.seatunnel.flink.SeatunnelFlink,讀者如果想直接深入瞭解作業啟動核心流程的話推薦閱讀這兩個類的原始碼,聯結器V2和聯結器V1的啟動流程基本一致。

SeaTunnel V2 on Spark

image-20220924002215205

SeaTunnel Source聯結器V2將異構資料來源接入,生成以SeaTunnelRow為基本單位的資料來源,在翻譯層實現了Spark DataSource API V2,翻譯層使得Spark可以接入以SeaTunnelRow為基本單位的資料來源,從而實現無縫接入Spark的目的。

關於Spark DataSource API V2的詳細資訊,讀者可以參考:https://www.databricks.com/session/apache-spark-data-source-v2,由於這篇文章的主題並不是介紹Spark的特性,所以筆者在這裡不過多贅述。

SeaTunnel V2 on Flink

image-20220924003457273

SeaTunnel Source聯結器V2將異構資料來源接入,生成以SeaTunnelRow為基本單位的資料來源,同時在翻譯層實現了Flink source functionFlink sink function,翻譯層使得Flink可以接入以SeaTunnelRow為基本單位的資料來源,從而實現無縫接入Flink的目的。

關於Flink source FunctionFlink sink function的詳細資訊,讀者可以參考:https://nightlies.apache.org/flink/flink-docs-release-1.15/docs/dev/datastream/sources/#the-data-source-api,由於這篇文章的主題並不是介紹Flink的特性,所以筆者在這裡不過多贅述。

執行原理

Source聯結器接入資料來源為SeaTunnelRow,Translation層轉換SeaTunnelRow資料來源為各種計算引擎內部的資料來源,Sink 聯結器接收計算引擎內部轉換好的SeaTunnelRow資料來源並寫入到目標資料來源中。

V1 API vs V2 API

特徵 聯結器V1 聯結器V2
引擎依賴 強依賴Spark、Flink 無依賴
聯結器實現 針對不同引擎要實現多次 只實現一遍
引擎版本升級難易程度 較難,聯結器與引擎高度耦合 較易,針對不同版本開發不同翻譯層即可
聯結器引數是否統一 針對不同引擎可能會有不同引數 引數統一
自定義分片邏輯 依賴Spark、Flink已經實現好的資料Connector,分片邏輯不可控 分片邏輯可自定義

未來展望

目前社群正在做的事情:

  1. 聯結器接入,社群計劃在年底接入80+種資料來源
  2. Web服務化,社群目前在做Web服務化相關工作,使用者可根據Web介面進行作業的管理、日誌檢視、上下線操作
  3. 計算引擎開發,社群目前在開發自己的計算引擎,更專注於資料同步,提升效能

未來目標:

  1. 效能優化,多維度指標監控,精確流速控制,視覺化大屏監控
  2. 視覺化拖拉拽快速生成資料整合任務
  3. 更多排程平臺無縫接入

最終目標:成功從Apache孵化器畢業,成為世界一流的誕生於中國的資料整合平臺工具

貢獻者招募

目前社群正在蓬勃向前發展,大量feature需要去開發實現,畢業之路道阻且艱,期待更多的有志之士參與到社群共建,歡迎熱愛開源的小夥伴加入SeaTunnel社群,有意者可發郵件至[email protected]或微信tyrantlucifer聯絡我諮詢相關事宜,讓我們一起用開源點燃璀璨的程式人生。