DataX-MysqlReader 插件文檔


MysqlReader 插件文檔


1 快速介紹

MysqlReader插件實現了從Mysql讀取數據。在底層實現上,MysqlReader通過JDBC連接遠程Mysql數據庫,並執行相應的sql語句將數據從mysql庫中SELECT出來。

不同於其他關系型數據庫,MysqlReader不支持FetchSize.

2 實現原理

簡而言之,MysqlReader通過JDBC連接器連接到遠程的Mysql數據庫,並根據用戶配置的信息生成查詢SELECT SQL語句,然后發送到遠程Mysql數據庫,並將該SQL執行返回結果使用DataX自定義的數據類型拼裝為抽象的數據集,並傳遞給下游Writer處理。

對於用戶配置Table、Column、Where的信息,MysqlReader將其拼接為SQL語句發送到Mysql數據庫;對於用戶配置querySql信息,MysqlReader直接將其發送到Mysql數據庫。

3 功能說明

3.1 配置樣例

  • 配置一個從Mysql數據庫同步抽取數據到本地的作業:
{
    "job": {
        "setting": {
            "speed": {
                 "channel": 3
            },
            "errorLimit": {
                "record": 0,
                "percentage": 0.02
            }
        },
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "username": "root",
                        "password": "root",
                        "column": [
                            "id",
                            "name"
                        ],
                        "splitPk": "db_id",
                        "connection": [
                            {
                                "table": [
                                    "table"
                                ],
                                "jdbcUrl": [
     "jdbc:mysql://127.0.0.1:3306/database"
                                ]
                            }
                        ]
                    }
                },
               "writer": {
                    "name": "streamwriter",
                    "parameter": {
                        "print":true
                    }
                }
            }
        ]
    }
}

  • 配置一個自定義SQL的數據庫同步任務到本地內容的作業:
{
    "job": {
        "setting": {
            "speed": {
                 "channel":1
            }
        },
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "username": "root",
                        "password": "root",
                        "connection": [
                            {
                                "querySql": [
                                    "select db_id,on_line_flag from db_info where db_id < 10;"
                                ],
                                "jdbcUrl": [
                                    "jdbc:mysql://bad_ip:3306/database",
                                    "jdbc:mysql://127.0.0.1:bad_port/database",
                                    "jdbc:mysql://127.0.0.1:3306/database"
                                ]
                            }
                        ]
                    }
                },
                "writer": {
                    "name": "streamwriter",
                    "parameter": {
                        "print": false,
                        "encoding": "UTF-8"
                    }
                }
            }
        ]
    }
}

3.2 參數說明

  • jdbcUrl

    • 描述:描述的是到對端數據庫的JDBC連接信息,使用JSON的數組描述,並支持一個庫填寫多個連接地址。之所以使用JSON數組描述連接信息,是因為阿里集團內部支持多個IP探測,如果配置了多個,MysqlReader可以依次探測ip的可連接性,直到選擇一個合法的IP。如果全部連接失敗,MysqlReader報錯。 注意,jdbcUrl必須包含在connection配置單元中。對於阿里集團外部使用情況,JSON數組填寫一個JDBC連接即可。

      jdbcUrl按照Mysql官方規范,並可以填寫連接附件控制信息。具體請參看Mysql官方文檔

    • 必選:是

    • 默認值:無

  • username

    • 描述:數據源的用戶名

    • 必選:是

    • 默認值:無

  • password

    • 描述:數據源指定用戶名的密碼

    • 必選:是

    • 默認值:無

  • table

    • 描述:所選取的需要同步的表。使用JSON的數組描述,因此支持多張表同時抽取。當配置為多張表時,用戶自己需保證多張表是同一schema結構,MysqlReader不予檢查表是否同一邏輯表。注意,table必須包含在connection配置單元中。

    • 必選:是

    • 默認值:無

  • column

    • 描述:所配置的表中需要同步的列名集合,使用JSON的數組描述字段信息。用戶使用*代表默認使用所有列配置,例如['*']。

      支持列裁剪,即列可以挑選部分列進行導出。

      支持列換序,即列可以不按照表schema信息進行導出。

      支持常量配置,用戶需要按照Mysql SQL語法格式: ["id", "`table`", "1", "'bazhen.csy'", "null", "to_char(a + 1)", "2.3" , "true"] id為普通列名,`table`為包含保留在的列名,1為整形數字常量,'bazhen.csy'為字符串常量,null為空指針,to_char(a + 1)為表達式,2.3為浮點數,true為布爾值。

    • 必選:是

    • 默認值:無

  • splitPk

    • 描述:MysqlReader進行數據抽取時,如果指定splitPk,表示用戶希望使用splitPk代表的字段進行數據分片,DataX因此會啟動並發任務進行數據同步,這樣可以大大提供數據同步的效能。

      推薦splitPk用戶使用表主鍵,因為表主鍵通常情況下比較均勻,因此切分出來的分片也不容易出現數據熱點。

      目前splitPk僅支持整形數據切分,不支持浮點、字符串、日期等其他類型。如果用戶指定其他非支持類型,MysqlReader將報錯!

      如果splitPk不填寫,包括不提供splitPk或者splitPk值為空,DataX視作使用單通道同步該表數據。

    • 必選:否

    • 默認值:空

  • where

    • 描述:篩選條件,MysqlReader根據指定的column、table、where條件拼接SQL,並根據這個SQL進行數據抽取。在實際業務場景中,往往會選擇當天的數據進行同步,可以將where條件指定為gmt_create > $bizdate 。注意:不可以將where條件指定為limit 10,limit不是SQL的合法where子句。

      where條件可以有效地進行業務增量同步。如果不填寫where語句,包括不提供wherekey或者value,DataX均視作同步全量數據。
    • 必選:否

    • 默認值:無

  • querySql

    • 描述:在有些業務場景下,where這一配置項不足以描述所篩選的條件,用戶可以通過該配置型來自定義篩選SQL。當用戶配置了這一項之后,DataX系統就會忽略table,column這些配置型,直接使用這個配置項的內容對數據進行篩選,例如需要進行多表join后同步數據,使用select a,b from table_a join table_b on table_a.id = table_b.id

    當用戶配置querySql時,MysqlReader直接忽略table、column、where條件的配置,querySql優先級大於table、column、where選項。

    • 必選:否

    • 默認值:無

3.3 類型轉換

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

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

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

請注意:

  • 除上述羅列字段類型外,其他類型均不支持
  • tinyint(1) DataX視作為整形
  • year DataX視作為字符串類型
  • bit DataX屬於未定義行為

4 性能報告

4.1 環境准備

4.1.1 數據特征

建表語句:

CREATE TABLE `tc_biz_vertical_test_0000` (
`biz_order_id` bigint(20) NOT NULL 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=gbk COMMENT='tc_biz_vertical'

單行記錄類似於:

biz_order_id: 888888888
   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運行負載
1 183185 18.11 29 0.6 31 0.6
1 183185 18.11 29 0.6 31 0.6
4 183185 18.11 29 0.6 31 0.6
4 329733 32.60 58 0.8 60 0.76
8 183185 18.11 29 0.6 31 0.6
8 549556 54.33 115 1.46 120 0.78

說明:

  1. 這里的單表,主鍵類型為 bigint(20),范圍為:190247559466810-570722244711460,從主鍵范圍划分看,數據分布均勻。
  2. 對單表如果沒有安裝主鍵切分,那么配置通道個數不會提升速度,效果與1個通道一樣。

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

通道數 DataX速度(Rec/s) DataX流量(MB/s) DataX機器網卡進入流量(MB/s) DataX機器運行負載 DB網卡流出流量(MB/s) DB運行負載
1 202241 20.06 31.5 1.0 32 1.1
4 726358 72.04 123.9 3.1 132 3.6
8 1074405 106.56 197 5.5 205 5.1
16 1227892 121.79 229.2 8.1 233 7.3

5 約束限制

5.1 主備同步數據恢復問題

主備同步問題指Mysql使用主從災備,備庫從主庫不間斷通過binlog恢復數據。由於主備數據同步存在一定的時間差,特別在於某些特定情況,例如網絡延遲等問題,導致備庫同步恢復的數據與主庫有較大差別,導致從備庫同步的數據不是一份當前時間的完整鏡像。

針對這個問題,我們提供了preSql功能,該功能待補充。

5.2 一致性約束

Mysql在數據存儲划分中屬於RDBMS系統,對外可以提供強一致性數據查詢接口。例如當一次同步任務啟動運行過程中,當該庫存在其他數據寫入方寫入數據時,MysqlReader完全不會獲取到寫入更新數據,這是由於數據庫本身的快照特性決定的。關於數據庫快照特性,請參看MVCC Wikipedia

上述是在MysqlReader單線程模型下數據同步一致性的特性,由於MysqlReader可以根據用戶配置信息使用了並發數據抽取,因此不能嚴格保證數據一致性:當MysqlReader根據splitPk進行數據切分后,會先后啟動多個並發任務完成數據同步。由於多個並發任務相互之間不屬於同一個讀事務,同時多個並發任務存在時間間隔。因此這份數據並不是完整的一致的數據快照信息。

針對多線程的一致性快照需求,在技術上目前無法實現,只能從工程角度解決,工程化的方式存在取舍,我們提供幾個解決思路給用戶,用戶可以自行選擇:

  1. 使用單線程同步,即不再進行數據切片。缺點是速度比較慢,但是能夠很好保證一致性。

  2. 關閉其他數據寫入方,保證當前數據為靜態數據,例如,鎖表、關閉備庫同步等等。缺點是可能影響在線業務。

5.3 數據庫編碼問題

Mysql本身的編碼設置非常靈活,包括指定編碼到庫、表、字段級別,甚至可以均不同編碼。優先級從高到低為字段、表、庫、實例。我們不推薦數據庫用戶設置如此混亂的編碼,最好在庫級別就統一到UTF-8。

MysqlReader底層使用JDBC進行數據抽取,JDBC天然適配各類編碼,並在底層進行了編碼轉換。因此MysqlReader不需用戶指定編碼,可以自動獲取編碼並轉碼。

對於Mysql底層寫入編碼和其設定的編碼不一致的混亂情況,MysqlReader對此無法識別,對此也無法提供解決方案,對於這類情況,導出有可能為亂碼

5.4 增量數據同步

MysqlReader使用JDBC SELECT語句完成數據抽取工作,因此可以使用SELECT...WHERE...進行增量數據抽取,方式有多種:

  • 數據庫在線應用寫入數據庫時,填充modify字段為更改時間戳,包括新增、更新、刪除(邏輯刪)。對於這類應用,MysqlReader只需要WHERE條件跟上一同步階段時間戳即可。
  • 對於新增流水型數據,MysqlReader可以WHERE條件后跟上一階段最大自增ID即可。

對於業務上無字段區分新增、修改數據情況,MysqlReader也無法進行增量數據同步,只能同步全量數據。

5.5 Sql安全性

MysqlReader提供querySql語句交給用戶自己實現SELECT抽取語句,MysqlReader本身對querySql不做任何安全性校驗。這塊交由DataX用戶方自己保證。

6 FAQ


Q: MysqlReader同步報錯,報錯信息為XXX

A: 網絡或者權限問題,請使用mysql命令行測試:

mysql -u<username> -p<password> -h<ip> -D<database> -e "select * from <表名>"

如果上述命令也報錯,那可以證實是環境問題,請聯系你的DBA。


免責聲明!

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



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