前言
企業正在經歷其數據資產的爆炸式增長,這些數據包括批式或流式傳輸的結構化、半結構化以及非結構化數據,隨著海量數據批量導入的場景的增多,企業對于 Data Pipeline 的需求也愈加復雜。新一代云原生實時數倉 SelectDB Cloud 作為一款運行于多云之上的云原生實時數據倉庫,致力于通過開箱即用的能力為客戶帶來簡單快速的數倉體驗。在生態方面,SelectDB Cloud 提供了豐富的數據連接器插件(Connector)來連接各種來自周邊大數據工具的數據源,內置 Kafka、Flink、Spark、DataX 等常見的 Connector。基于此,企業開發者能夠更加便捷的將數據移動到 SelectDB Cloud 上,并利用 SelectDB Cloud 從數據資產中獲取更高的價值。
SelectDB Cloud 基于 Apache Doris 研發的新一代云原生實時數倉 SelectDB,運行于多家云上,為客戶提供極簡運維和極致性價比的數倉服務
介紹
DataX 是一個異構數據源離線同步工具,致力于實現包括關系型數據庫(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP,等各種異構數據源之間穩定高效的數據同步功能。
Selectdb 提供了datax-selectdb-writer 插件,可以將datax 支持的數據源同步到selectdb中
框架設計
主要分為三個部分:Reader,FrameWork,Writer
- Reader:Reader為數據采集模塊,負責采集數據源的數據,將數據發送給Framework。
- Writer: Writer為數據寫入模塊,負責不斷向Framework取數據,并將數據寫入到目的端。
- Framework:Framework用于連接reader和writer,作為兩者的數據傳輸通道,并處理緩沖,流控,并發,數據轉換等核心技術問題。
執行流程
- DataX完成單個數據同步的作業,我們稱之為Job,DataX接受到一個Job之后,將啟動一個進程來完成整個作業同步過程。DataX Job模塊是單個作業的中樞管理節點,承擔了數據清理、子任務切分(將單一作業計算轉化為多個子Task)、TaskGroup管理等功能。
- DataXJob啟動后,會根據不同的源端切分策略,將Job切分成多個小的Task(子任務),以便于并發執行。Task便是DataX作業的最小單元,每一個Task都會負責一部分數據的同步工作。
- 切分多個Task之后,DataX Job會調用Scheduler模塊,根據配置的并發數據量,將拆分成的Task重新組合,組裝成TaskGroup(任務組)。每一個TaskGroup負責以一定的并發運行完畢分配好的所有Task,默認單個任務組的并發數量為5。
- 每一個Task都由TaskGroup負責啟動,Task啟動后,會固定啟動Reader—>Channel—>Writer的線程來完成任務同步工作。
- DataX作業運行起來之后, Job監控并等待多個TaskGroup模塊任務完成,等待所有TaskGroup任務完成后Job成功退出。否則,異常退出,進程退出值非0
Selectdb writer介紹
1. 快速介紹
該插件主要將 MySQL、Oracle 等數據庫中的數據導入至 SELECTDB。該插件將數據轉化為 CSV 或 JSON 格式并將其通過 copy into 方式批量導入至 SELECTDB。
- 實現原理
SelectdbWriter 通過調用selectdb upload api,返回一個重定向的S3地址,使用Http向S3地址發送字節流,設置參數達到要求時執行copy into
3. 編譯
1. 下載
git clone https://github.com/selectdb/datax-selectdb.git
2. 運行 init-env.sh
這個腳本主要用于構建 DataX 開發環境,他主要進行了以下操作: 1 .將 DataX 代碼庫 clone 到本地。 2. 將 doriswriter/ 目錄軟鏈到 DataX/selectdbwriter 目錄。 3. 在 DataX/pom.xml 文件中添加 <module>selectdbwriter</module> 模塊。 4. 這個腳本執行后,開發者就可以進入 DataX/ 目錄開始開發或編譯了。因為做了軟鏈, 所以任何對 DataX/doriswriter 目錄中文件的修改,都會反映到 doriswriter/ 目錄中, 方便開發者提交代碼。
3. 編譯 selectdbwriter
- 編譯整個 DataX 項目
mvn package assembly:assembly -Dmaven.test.skip=true
產出在 target/datax/datax/. hdfsreader, hdfswriter and oscarwriter 這三個插件需要額外的jar包。如果你并不需要這些插件,可以在 DataX/pom.xml 中刪除這些插件的模塊。
- 單獨編譯 doriswriter 插件
mvn clean install -pl plugin-rdbms-util,doriswriter -DskipTests
- 編譯錯誤
如遇到如下編譯錯誤:
Could not find artifact com.alibaba.datax:datax-all:pom:0.0.1-SNAPSHOT ...
可嘗試以下方式解決:
- 下載 alibaba-datax-maven-m2-20210928.tar.gz
- 解壓后,將得到的
alibaba/datax/
目錄,拷貝到所使用的 maven 對應的.m2/repository/com/alibaba/
下。 - 再次嘗試編譯。
- 示例
- 配置樣例
這里是一份從Stream讀取數據后導入至selectdb的配置文件。
{
"job":{
"content":[
{
"reader":{
"name":"streamreader",
"parameter":{
"column":[
{
"type":"string",
"random":"0,31"
},
{
"type":"string",
"random":"0,31"
},
{
"type":"string",
"random":"0,31"
},
{
"type":"string",
"random":"0,31"
},
{
"type":"long",
"random":"0,5"
},
{
"type":"string",
"random":"0,10"
},
{
"type":"string",
"random":"0,5"
},
{
"type":"string",
"random":"0,31"
},
{
"type":"string",
"random":"0,31"
},
{
"type":"string",
"random":"0,21"
},
{
"type":"string",
"random":"0,31"
},
{
"type":"long",
"random":"0,10"
},
{
"type":"long",
"random":"0,20"
},
{
"type":"date",
"random":"2022-01-01 12:00:00,2023-01-01 12:00:00"
},
{
"type":"long",
"random":"0,10"
},
{
"type":"date",
"random":"2022-01-01 12:00:00,2023-01-01 12:00:00"
},
{
"type":"string",
"random":"0,10"
},
{
"type":"long",
"random":"0,10"
},
{
"type":"date",
"random":"2022-01-01 12:00:00,2023-01-01 12:00:00"
},
{
"type":"long",
"random":"0,10"
},
{
"type":"date",
"random":"2022-01-01 12:00:00,2023-01-01 12:00:00"
},
{
"type":"long",
"random":"0,10"
},
{
"type":"date",
"random":"2022-01-01 12:00:00,2023-01-01 12:00:00"
},
{
"type":"long",
"random":"0,10"
},
{
"type":"date",
"random":"2022-01-01 12:00:00,2023-01-01 12:00:00"
},
{
"type":"string",
"random":"0,100"
},
{
"type":"string",
"random":"0,1"
},
{
"type":"long",
"random":"0,1"
},
{
"type":"string",
"random":"0,64"
},
{
"type":"string",
"random":"0,20"
},
{
"type":"string",
"random":"0,31"
},
{
"type":"long",
"random":"0,3"
},
{
"type":"long",
"random":"0,3"
},
{
"type":"long",
"random":"0,19"
},
{
"type":"date",
"random":"2022-01-01 12:00:00,2023-01-01 12:00:00"
},
{
"type":"string",
"random":"0,1"
}
],
"sliceRecordCount":10
}
},
"writer":{
"name":"selectdbwriter",
"parameter":{
"loadUrl":[
"xxx:47150"
],
"loadProps":{
"file.type":"json",
"file.strip_outer_array":"true"
},
"column":[
"id",
"table_id",
"table_no",
"table_name",
"table_status",
"no_disturb",
"dinner_type",
"member_id",
"reserve_bill_no",
"pre_order_no",
"queue_num",
"person_num",
"open_time",
"open_time_format",
"order_time",
"order_time_format",
"table_bill_id",
"offer_time",
"offer_time_format",
"confirm_bill_time",
"confirm_bill_time_format",
"bill_time",
"bill_time_format",
"clear_time",
"clear_time_format",
"table_message",
"bill_close",
"table_type",
"pad_mac",
"company_id",
"shop_id",
"is_sync",
"table_split_no",
"ts",
"ts_format",
"dr"
],
"username":"admin",
"password":"",
"postSql":[
],
"preSql":[
],
"connection":[
{
"jdbcUrl":"jdbc:mysql://xxx:34142/cl_test",
"table":[
"ods_pos_pro_table_dynamic_delta_v4"
],
"selectedDatabase":"cl_test"
}
],
"maxBatchRows":1000000,
"maxBatchByteSize":536870912000
}
}
}
],
"setting":{
"errorLimit":{
"percentage":0.02,
"record":0
},
"speed":{
"channel":5
}
}
}
}
- 執行任務
python $DATAX_HOME/datax.py ../xx.json
- 參數說明
**jdbcUrl**
- 描述:selectdb 的 JDBC 連接串,用戶執行 preSql 或 postSQL。
- 必選:是
- 默認值:無
* **loadUrl**
- 描述:作為 selecdb 的連接目標。格式為 "ip:port"。其中 IP 是 selectdb的private-link,port 是selectdb 集群的 http_port
- 必選:是
- 默認值:無
* **username**
- 描述:訪問selectdb數據庫的用戶名
- 必選:是
- 默認值:無
* **password**
- 描述:訪問selectdb數據庫的密碼
- 必選:否
- 默認值:空
* **connection.selectedDatabase**
- 描述:需要寫入的selectdb數據庫名稱。
- 必選:是
- 默認值:無
* **connection.table**
- 描述:需要寫入的selectdb表名稱。
- 必選:是
- 默認值:無
* **column**
- 描述:目的表**需要寫入數據**的字段,這些字段將作為生成的 Json 數據的字段名。字段之間用英文逗號分隔。例如: "column": ["id","name","age"]。
- 必選:是
- 默認值:否
* **preSql**
- 描述:寫入數據到目的表前,會先執行這里的標準語句。
- 必選:否
- 默認值:無
* **postSql**
- 描述:寫入數據到目的表后,會執行這里的標準語句。
- 必選:否
- 默認值:無
* **maxBatchRows**
- 描述:每批次導入數據的最大行數。和 **batchSize** 共同控制每批次的導入數量。每批次數據達到兩個閾值之一,即開始導入這一批次的數據。
- 必選:否
- 默認值:500000
* **batchSize**
- 描述:每批次導入數據的最大數據量。和 **maxBatchRows** 共同控制每批次的導入數量。每批次數據達到兩個閾值之一,即開始導入這一批次的數據。
- 必選:否
- 默認值:90M
* **maxRetries**
- 描述:每批次導入數據失敗后的重試次數。
- 必選:否
- 默認值:3
* **labelPrefix**
- 描述:每批次上傳文件的 label 前綴。最終的 label 將有 `labelPrefix + UUID` 組成全局唯一的 label,確保數據不會重復導入
- 必選:否
- 默認值:`datax_selectdb_writer_`
* **loadProps**
- 描述:COPY INOT 的請求參數
這里包括導入的數據格式:file.type等,導入數據格式默認我們使用csv,支持JSON,具體可以參照下面類型轉換部分
- 必選:否
- 默認值:無
* **clusterName**
- 描述:selectdb could 集群名稱
- 必選:否
- 默認值:無
* **flushQueueLength**
- 描述:隊列長度
- 必選:否
- 默認值:1
* **flushInterval**
- 描述:數據寫入批次的時間間隔,如果maxBatchRows 和 batchSize 參數設置的有很大,那么很可能達不到你這設置的數據量大小,會執行導入。
- 必選:否
- 默認值:30000ms
- 類型轉化
默認傳入的數據均會被轉為字符串,并以\t
作為列分隔符,\n
作為行分隔符,組成csv
文件進行Selectdb導入操作。
默認是csv格式導入,如需更改列分隔符, 則正確配置 loadProps
即可:
"loadProps": { "file.column_separator": "\\x01", "file.line_delimiter": "\\x02" }
如需更改導入格式為json
, 則正確配置 loadProps
即可:
"loadProps": { "file.type": "json", "file.strip_outer_array": true }