DataX-MysqlWriter 插件文檔


DataX MysqlWriter


1 快速介紹

MysqlWriter 插件實現了寫入數據到 Mysql 主庫的目的表的功能。在底層實現上, MysqlWriter 通過 JDBC 連接遠程 Mysql 數據庫,並執行相應的 insert into ... 或者 ( replace into ...) 的 sql 語句將數據寫入 Mysql,內部會分批次提交入庫,需要數據庫本身采用 innodb 引擎。

MysqlWriter 面向ETL開發工程師,他們使用 MysqlWriter 從數倉導入數據到 Mysql。同時 MysqlWriter 亦可以作為數據遷移工具為DBA等用戶提供服務。

2 實現原理

MysqlWriter 通過 DataX 框架獲取 Reader 生成的協議數據,根據你配置的 writeMode 生成

  • insert into...(當主鍵/唯一性索引沖突時會寫不進去沖突的行)
或者
  • replace into...(沒有遇到主鍵/唯一性索引沖突時,與 insert into 行為一致,沖突時會用新行替換原有行所有字段) 的語句寫入數據到 Mysql。出於性能考慮,采用了 PreparedStatement + Batch,並且設置了:rewriteBatchedStatements=true,將數據緩沖到線程上下文 Buffer 中,當 Buffer 累計到預定閾值時,才發起寫入請求。

注意:目的表所在數據庫必須是主庫才能寫入數據;整個任務至少需要具備 insert/replace into...的權限,是否需要其他權限,取決於你任務配置中在 preSql 和 postSql 中指定的語句。

3 功能說明

3.1 配置樣例

  • 這里使用一份從內存產生到 Mysql 導入的數據。
{
    "job": {
        "setting": {
            "speed": {
                "channel": 1
            }
        },
        "content": [
            {
                 "reader": {
                    "name": "streamreader",
                    "parameter": {
                        "column" : [
                            {
                                "value": "DataX",
                                "type": "string"
                            },
                            {
                                "value": 19880808,
                                "type": "long"
                            },
                            {
                                "value": "1988-08-08 08:08:08",
                                "type": "date"
                            },
                            {
                                "value": true,
                                "type": "bool"
                            },
                            {
                                "value": "test",
                                "type": "bytes"
                            }
                        ],
                        "sliceRecordCount": 1000
                    }
                },
                "writer": {
                    "name": "mysqlwriter",
                    "parameter": {
                        "writeMode": "insert",
                        "username": "root",
                        "password": "root",
                        "column": [
                            "id",
                            "name"
                        ],
                        "session": [
                        	"set session sql_mode='ANSI'"
                        ],
                        "preSql": [
                            "delete from test"
                        ],
                        "connection": [
                            {
                                "jdbcUrl": "jdbc:mysql://127.0.0.1:3306/datax?useUnicode=true&characterEncoding=gbk",
                                "table": [
                                    "test"
                                ]
                            }
                        ]
                    }
                }
            }
        ]
    }
}

3.2 參數說明

  • jdbcUrl

    • 描述:目的數據庫的 JDBC 連接信息。作業運行時,DataX 會在你提供的 jdbcUrl 后面追加如下屬性:yearIsDateType=false&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true

      注意:1、在一個數據庫上只能配置一個 jdbcUrl 值。這與 MysqlReader 支持多個備庫探測不同,因為此處不支持同一個數據庫存在多個主庫的情況(雙主導入數據情況)
                2、jdbcUrl按照Mysql官方規范,並可以填寫連接附加控制信息,比如想指定連接編碼為 gbk ,則在 jdbcUrl 后面追加屬性 useUnicode=true&characterEncoding=gbk。具體請參看 Mysql官方文檔或者咨詢對應 DBA。
    • 必選:是

    • 默認值:無

  • username

    • 描述:目的數據庫的用戶名

    • 必選:是

    • 默認值:無

  • password

    • 描述:目的數據庫的密碼

    • 必選:是

    • 默認值:無

  • table

    • 描述:目的表的表名稱。支持寫入一個或者多個表。當配置為多張表時,必須確保所有表結構保持一致。

      注意:table 和 jdbcUrl 必須包含在 connection 配置單元中
    • 必選:是

    • 默認值:無

  • column

    • 描述:目的表需要寫入數據的字段,字段之間用英文逗號分隔。例如: "column": ["id","name","age"]。如果要依次寫入全部列,使用表示, 例如: "column": [""]。

      **column配置項必須指定,不能留空!**
      
           注意:1、我們強烈不推薦你這樣配置,因為當你目的表字段個數、類型等有改動時,你的任務可能運行不正確或者失敗
                2、 column 不能配置任何常量值
    • 必選:是

    • 默認值:否

  • session

    • 描述: DataX在獲取Mysql連接時,執行session指定的SQL語句,修改當前connection session屬性

    • 必須: 否

    • 默認值: 空

  • preSql

    • 描述:寫入數據到目的表前,會先執行這里的標准語句。如果 Sql 中有你需要操作到的表名稱,請使用 @table 表示,這樣在實際執行 Sql 語句時,會對變量按照實際表名稱進行替換。比如你的任務是要寫入到目的端的100個同構分表(表名稱為:datax_00,datax01, ... datax_98,datax_99),並且你希望導入數據前,先對表中數據進行刪除操作,那么你可以這樣配置:"preSql":["delete from 表名"],效果是:在執行到每個表寫入數據前,會先執行對應的 delete from 對應表名稱

    • 必選:否

    • 默認值:無

  • postSql

    • 描述:寫入數據到目的表后,會執行這里的標准語句。(原理同 preSql )

    • 必選:否

    • 默認值:無

  • writeMode

    • 描述:控制寫入數據到目標表采用 insert into 或者 replace into 或者 ON DUPLICATE KEY UPDATE 語句

    • 必選:是

    • 所有選項:insert/replace/update

    • 默認值:insert

  • batchSize

    • 描述:一次性批量提交的記錄數大小,該值可以極大減少DataX與Mysql的網絡交互次數,並提升整體吞吐量。但是該值設置過大可能會造成DataX運行進程OOM情況。

    • 必選:否

    • 默認值:1024

3.3 類型轉換

類似 MysqlReader ,目前 MysqlWriter 支持大部分 Mysql 類型,但也存在部分個別類型沒有支持的情況,請注意檢查你的類型。

下面列出 MysqlWriter 針對 Mysql 類型轉換列表:

DataX 內部類型 Mysql 數據類型
Long int, tinyint, smallint, mediumint, int, bigint, year
Double float, double, decimal
String varchar, char, tinytext, text, mediumtext, longtext
Date date, datetime, timestamp, time
Boolean bit, bool
Bytes tinyblob, mediumblob, blob, longblob, varbinary
  • bit類型目前是未定義類型轉換

4 性能報告

4.1 環境准備

4.1.1 數據特征

建表語句:

CREATE TABLE `datax_mysqlwriter_perf_00` (
`biz_order_id` bigint(20) NOT NULL AUTO_INCREMENT  COMMENT 'id',
`key_value` varchar(4000) NOT NULL COMMENT 'Key-value的內容',
`gmt_create` datetime NOT NULL COMMENT '創建時間',
`gmt_modified` datetime NOT NULL COMMENT '修改時間',
`attribute_cc` int(11) DEFAULT NULL COMMENT '防止並發修改的標志',
`value_type` int(11) NOT NULL DEFAULT '0' COMMENT '類型',
`buyer_id` bigint(20) DEFAULT NULL COMMENT 'buyerid',
`seller_id` bigint(20) DEFAULT NULL COMMENT 'seller_id',
PRIMARY KEY (`biz_order_id`,`value_type`),
KEY `idx_biz_vertical_gmtmodified` (`gmt_modified`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='datax perf test'

單行記錄類似於:

key_value: ;orderIds:20148888888,2014888888813800;
  gmt_create: 2011-09-24 11:07:20
gmt_modified: 2011-10-24 17:56:34
attribute_cc: 1
  value_type: 3
	buyer_id: 8888888
   seller_id: 1

4.1.2 機器參數

  • 執行DataX的機器參數為:

    1. cpu: 24核 Intel(R) Xeon(R) CPU E5-2630 0 @ 2.30GHz
    2. mem: 48GB
    3. net: 千兆雙網卡
    4. disc: DataX 數據不落磁盤,不統計此項
  • Mysql數據庫機器參數為:

    1. cpu: 32核 Intel(R) Xeon(R) CPU E5-2650 v2 @ 2.60GHz
    2. mem: 256GB
    3. net: 千兆雙網卡
    4. disc: BTWL419303E2800RGN INTEL SSDSC2BB800G4 D2010370

4.1.3 DataX jvm 參數

-Xms1024m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError

4.2 測試報告

4.2.1 單表測試報告

通道數 批量提交行數 DataX速度(Rec/s) DataX流量(MB/s) DataX機器網卡流出流量(MB/s) DataX機器運行負載 DB網卡進入流量(MB/s) DB運行負載 DB TPS
1 128 5319 0.260 0.580 0.05 0.620 0.5 50
1 512 14285 0.697 1.6 0.12 1.6 0.6 28
1 1024 17241 0.842 1.9 0.20 1.9 0.6 16
1 2048 31250 1.49 2.8 0.15 3.0 0.8 15
1 4096 31250 1.49 3.5 0.20 3.6 0.8 8
4 128 11764 0.574 1.5 0.21 1.6 0.8 112
4 512 30769 1.47 3.5 0.3 3.6 0.9 88
4 1024 50000 2.38 5.4 0.3 5.5 1.0 66
4 2048 66666 3.18 7.0 0.3 7.1 1.37 46
4 4096 80000 3.81 7.3 0.5 7.3 1.40 26
8 128 17777 0.868 2.9 0.28 2.9 0.8 200
8 512 57142 2.72 8.5 0.5 8.5 0.70 159
8 1024 88888 4.24 12.2 0.9 12.4 1.0 108
8 2048 133333 6.36 14.7 0.9 14.7 1.0 81
8 4096 166666 7.95 19.5 0.9 19.5 3.0 45
16 128 32000 1.53 3.3 0.6 3.4 0.88 401
16 512 106666 5.09 16.1 0.9 16.2 2.16 260
16 1024 173913 8.29 22.1 1.5 22.2 4.5 200
16 2048 228571 10.90 28.6 1.61 28.7 4.60 128
16 4096 246153 11.74 31.1 1.65 31.2 4.66 57
32 1024 246153 11.74 30.5 3.17 30.7 12.10 270

說明:

  1. 這里的單表,主鍵類型為 bigint(20),自增。
  2. batchSize 和 通道個數,對性能影響較大。
  3. 16通道,4096批量提交時,出現 full gc 2次。

4.2.2 分表測試報告(2個分庫,每個分庫4張分表,共計8張分表)

通道數 批量提交行數 DataX速度(Rec/s) DataX流量(MB/s) DataX機器網卡流出流量(MB/s) DataX機器運行負載 DB網卡進入流量(MB/s) DB運行負載 DB TPS
8 128 26764 1.28 2.9 0.5 3.0 0.8 209
8 512 95180 4.54 10.5 0.7 10.9 0.8 188
8 1024 94117 4.49 12.3 0.6 12.4 1.09 120
8 2048 133333 6.36 19.4 0.9 19.5 1.35 85
8 4096 191692 9.14 22.1 1.0 22.2 1.45 45

4.2.3 分表測試報告(2個分庫,每個分庫8張分表,共計16張分表)

通道數 批量提交行數 DataX速度(Rec/s) DataX流量(MB/s) DataX機器網卡流出流量(MB/s) DataX機器運行負載 DB網卡進入流量(MB/s) DB運行負載 DB TPS
16 128 50124 2.39 5.6 0.40 6.0 2.42 378
16 512 155084 7.40 18.6 1.30 18.9 2.82 325
16 1024 177777 8.48 24.1 1.43 25.5 3.5 233
16 2048 289382 13.8 33.1 2.5 33.5 4.5 150
16 4096 326451 15.52 33.7 1.5 33.9 4.3 80

4.2.4 性能測試小結

  1. 批量提交行數(batchSize)對性能影響很大,當 batchSize>=512 之后,單線程寫入速度能達到每秒寫入一萬行
  2. batchSize>=512 的基礎上,隨着通道數的增加(通道數<32),速度呈線性比增加。
  3. 通常不建議寫入數據庫時,通道個數 >32

5 約束限制

FAQ


Q: MysqlWriter 執行 postSql 語句報錯,那么數據導入到目標數據庫了嗎?

A: DataX 導入過程存在三塊邏輯,pre 操作、導入操作、post 操作,其中任意一環報錯,DataX 作業報錯。由於 DataX 不能保證在同一個事務完成上述幾個操作,因此有可能數據已經落入到目標端。


Q: 按照上述說法,那么有部分臟數據導入數據庫,如果影響到線上數據庫怎么辦?

A: 目前有兩種解法,第一種配置 pre 語句,該 sql 可以清理當天導入數據, DataX 每次導入時候可以把上次清理干凈並導入完整數據。第二種,向臨時表導入數據,完成后再 rename 到線上表。


Q: 上面第二種方法可以避免對線上數據造成影響,那我具體怎樣操作?

A: 可以配置臨時表導入


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM