DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL、Oracle、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、DRDS 等各种异构数据源之间高效的数据同步功能。
关于原理及优缺点,知乎上有博主描述:DataX介绍以及优缺点分析 - 知乎
笔者比较赞同
官方部分参数说明(这里以Oracle读,Oracle写为例,关系型数据库参数基本一样)
{
"job": {
"setting": {
"speed": {
// 设置传输速度 byte/s 尽量逼近这个速度但是不高于它.
// channel 表示通道数量,byte表示通道速度,如果单通道速度1MB,
配置byte为1048576表示一个channel
"byte": 1048576
},
//出错限制
"errorLimit": {
//先选择record,出错多少条抛异常,为零代表报错就抛异常,任务失败
"record": 0,
//百分比 1表示100%
"percentage": 0.02
}
},
"content": [
{
"reader": {
"name": "oraclereader",
"parameter": {
// 数据库连接用户名
"username": "root",
// 数据库连接密码
"password": "root",
"column": [
"id","name"
],
//切分主键
"splitPk": "db_id",
"connection": [
{
"table": [
"table"
],
"jdbcUrl": [
"jdbc:oracle:thin:@[HOST_NAME]:PORT:[DATABASE_NAME]"
]
}
]
}
},
"writer": {
"name": "oraclewriter",
"parameter": {
"username": "root",
"password": "root",
"column": [
"id",
"name"
],
"preSql": [
"delete from test"
],
"connection": [
{
"jdbcUrl": "jdbc:oracle:thin:@[HOST_NAME]:PORT:[DATABASE_NAME]",
"table": [
"test"
]
}
]
}
}
}
]
}
}
setting:
speed:数据传输速度
channel:通道数量
byte:传输速度 byte/s 尽量逼近这个速度但是不高于它
errorLimit:数据容错数
record:出错多少条抛异常,为零代表报错就抛异常,任务失败
percentage:出错率,1表示100%,条数和概率都配置了则优先条数然后再判断百分比
content:
reader:
name:根据读取的数据源固定名称:*reader,例如【mysqlreader,oraclereader,sqlserverreader...】
fetchSize:mysql不支持这个参数,该配置项定义了插件和数据库服务器端每次批量数据获取条数,该值决定了DataX和服务器端的网络交互次数,能够较大的提升数据抽取性能。不宜设置过大超过2048可能会造成Datax进程OOM,默认1024
parameter:
username:数据库用户名
password: 数据库密码
splitPk:进行数据抽取时,如果指定splitPk,表示用户希望使用splitPk代表的字段进行数据分片,DataX因此会启动并发任务进行数据同步,这样可以大大提供数据同步的效能。推荐splitPk用户使用表主键,因为表主键通常情况下比较均匀,因此切分出来的分片也不容易出现数据热点。目前splitPk仅支持整形、字符串型数据切分
column:指定列(注意,如果设置了querySql,此字段可以不写)
where:查询条件(注意,如果设置了querySql,此字段可以不写)
connection:
table:指定表名(注意,如果设置了querySql,此字段可以不写)
querySql:指定查询的sql语句(描述:在有些业务场景下,where这一配置项不足以描述所筛选的条件,用户可以通过该配置型来自定义筛选SQL。当用户配置了这一项之后,DataX系统就会忽略table,column这些配置型,直接使用这个配置项的内容对数据进行筛选,例如需要进行多表join后同步数据,使用select a,b from table_a join table_b on table_a.id = table_b.id;个人推荐使用,如果不设置,请填写column和table两个字段,where可以不写,会默认全表数据,如果设置了column,table,where三个字段会失效)
jdbcUrl:指定数据库连接
writer:
name:根据写入的数据源固定名称:*writer,例如【mysqlwriter,oraclewriter,sqlserverwriter...】
parameter:
username:数据库用户名
password: 数据库密码
writeMode:oracle,postgresql,sqlserver不支持这个参数,控制写入数据到目标表采用 insert into 或者 replace into 或者 ON DUPLICATE KEY UPDATE 语句,所有选择(insert/replace/update)
column:指定列
preSql:写入数据到目的表前,会先执行这里的标准语句。
postSql:写入数据到目的表后,会执行这里的标准语句。
batchSize:一次性批量提交的记录数大小,该值可以极大减少DataX与Mysql的网络交互次数,并提升整体吞吐量。但是该值设置过大可能会造成DataX运行进程OOM情况。默认1024
session:描述:控制写入数据的时间格式,时区等的配置,如果表中有时间字段,配置该值以明确告知写入 oracle 的时间格式。通常配置的参数为:NLS_DATE_FORMAT,NLS_TIME_FORMAT。其配置的值为 json 格式
例如
"session": [
"alter session set NLS_DATE_FORMAT='yyyy-mm-dd hh24:mi:ss'",
"alter session set NLS_TIMESTAMP_FORMAT='yyyy-mm-dd hh24:mi:ss'",
"alter session set NLS_TIMESTAMP_TZ_FORMAT='yyyy-mm-dd hh24:mi:ss'",
"alter session set TIME_ZONE='US/Pacific'",
"set session sql_mode='ANSI'"
]
connection:
table:指定表名
jdbcUrl:指定数据库连接
执行 DataX 的机器参数为:
cpu: 24 Core Intel(R) Xeon(R) CPU E5-2430 0 @ 2.20GHz
mem: 94GB
net: 千兆双网卡
disc: DataX 数据不落磁盘,不统计此项
Oracle 数据库机器参数为:
cpu: 4 Core Intel(R) Xeon(R) CPU E5420 @ 2.50GHz
mem: 7GB
DataX jvm 参数
-Xms1024m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError
通道数 |
批量提交行数 |
DataX速度(Rec/s) |
DataX流量(MB/s) |
DataX机器网卡流出流量(MB/s) |
DataX机器运行负载 |
DB网卡进入流量(MB/s) |
DB运行负载 |
1 |
128 |
15564 |
6.51 |
7.5 |
0.02 |
7.4 |
1.08 |
1 |
512 |
29491 |
10.90 |
12.6 |
0.05 |
12.4 |
1.55 |
1 |
1024 |
31529 |
11.87 |
13.5 |
0.22 |
13.3 |
1.58 |
1 |
2048 |
33469 |
12.57 |
14.3 |
0.17 |
14.3 |
1.53 |
1 |
4096 |
31363 |
12.48 |
13.4 |
0.10 |
10.0 |
1.72 |
4 |
10 |
9440 |
4.05 |
5.6 |
0.01 |
5.0 |
3.75 |
4 |
128 |
42832 |
16.48 |
18.3 |
0.07 |
18.5 |
2.89 |
4 |
512 |
46643 |
20.02 |
22.7 |
0.35 |
21.1 |
3.31 |
4 |
1024 |
39116 |
16.79 |
18.7 |
0.10 |
18.1 |
3.05 |
4 |
2048 |
39526 |
16.96 |
18.5 |
0.32 |
17.1 |
2.86 |
4 |
4096 |
37683 |
16.17 |
17.2 |
0.23 |
15.5 |
2.26 |
8 |
128 |
38336 |
16.45 |
17.5 |
0.13 |
16.2 |
3.87 |
8 |
512 |
31078 |
13.34 |
14.9 |
0.11 |
13.4 |
2.09 |
8 |
1024 |
37888 |
16.26 |
18.5 |
0.20 |
18.5 |
3.14 |
8 |
2048 |
38502 |
16.52 |
18.5 |
0.18 |
18.5 |
2.96 |
8 |
4096 |
38092 |
16.35 |
18.3 |
0.10 |
17.8 |
3.19 |
16 |
128 |
35366 |
15.18 |
16.9 |
0.13 |
15.6 |
3.49 |
16 |
512 |
35584 |
15.27 |
16.8 |
0.23 |
17.4 |
3.05 |
16 |
1024 |
38297 |
16.44 |
17.5 |
0.20 |
17.0 |
3.42 |
16 |
2048 |
28467 |
12.22 |
13.8 |
0.10 |
12.4 |
3.38 |
16 |
4096 |
27852 |
11.95 |
12.3 |
0.11 |
12.3 |
3.86 |
32 |
1024 |
34406 |
14.77 |
15.4 |
0.09 |
15.4 |
3.55 |
批量提交行数(batchSize)对性能影响很大,当 batchSize>=512 之后,单线程写入速度能达到每秒写入一万行
在 batchSize>=512 的基础上,随着通道数的增加(通道数<32),速度呈线性比增加。
通常不建议写入数据库时,通道个数 >32
参数解释参照github上的官方文档,基本较全,读者也可自行登录官方地址查阅
读mysql数据写入到oracle
读数据源mysql表名:datax_test 字段:id,name, create_time
写数据源oracle表名:DATAX_TEST1 字段:ID1,NAME1,CREATE_TIME1
{
"job": {
"setting": {
"speed": {
"channel": 1,
"byte": 1048576
},
"errorLimit": {
"record": 0,
"percentage": 0.02
}
},
"content": [
{
"reader": {
"name": "mysqlreader",
"parameter": {
"username": "root",
"password": "root",
"splitPk": "id",
"connection": [
{
"querySql": [
"SELECT id ID1,name NAME1,create_time CREATE_TIME1 FROM datax_test"
],
"jdbcUrl": [
"jdbc:mysql://127.0.0.1:3306/mysql?useCursorFetch=true"
]
}
]
}
},
"writer": {
"name": "oraclewriter",
"parameter": {
"username": "root",
"password": "root",
"column": [
"\"ID1\"",
"\"NAME1\"",
"\"CREATE_TIME1\""
],
"connection": [
{
"table": [
"DATAX_TEST1"
],
"jdbcUrl": "jdbc:oracle:thin:@127.0.0.1:1521:orcl"
}
]
}
}
}
]
}
}
2.读oracle数据写入到oracle
读数据源oracle表名:DATAX_TEST 字段:ID,NAME, CREATE_TIME
写数据源oracle表名:DATAX_TEST1 字段:ID1,NAME1,CREATE_TIME1
{
"job": {
"setting": {
"speed": {
"channel": 1,
"byte": 1048576
},
"errorLimit": {
"record": 0,
"percentage": 0.02
}
},
"content": [
{
"reader": {
"name": "oraclereader",
"parameter": {
"username": "root",
"password": "root",
"splitPk": "ID",
"connection": [
{
"querySql": [
"SELECT ID ID1,NAME NAME1,CREATE_TIME CREATE_TIME1 FROM DATAX_TEST"
],
"jdbcUrl": [
"jdbc:oracle:thin:@127.0.0.1:1521:orcl"
]
}
]
}
},
"writer": {
"name": "oraclewriter",
"parameter": {
"username": "root",
"password": "root",
"column": [
"\"ID1\"",
"\"NAME1\"",
"\"CREATE_TIME1\""
],
"connection": [
{
"table": [
"DATAX_TEST1"
],
"jdbcUrl": "jdbc:oracle:thin:@127.0.0.1:1521:orcl"
}
]
}
}
}
]
}
}
3.读sqlserver数据写入到oracle
读数据源sqlserver表名:[guest].[datax_test] 字段:id,name, create_time
写数据源oracle表名:DATAX_TEST1 字段:ID1,NAME1,CREATE_TIME1
{
"job": {
"setting": {
"speed": {
"channel": 1,
"byte": 1048576
},
"errorLimit": {
"record": 0,
"percentage": 0.02
}
},
"content": [
{
"reader": {
"name": "sqlserverreader",
"parameter": {
"username": "root",
"password": "root",
"splitPk": "id",
"connection": [
{
"querySql": [
"SELECT id ID1,name NAME1,create_time CREATE_TIME1 FROM [guest].[datax_test]"
],
"jdbcUrl": [
"jdbc:sqlserver://127.0.0.1:1433;DatabaseName=DRGSTEST"
]
}
]
}
},
"writer": {
"name": "oraclewriter",
"parameter": {
"username": "root",
"password": "root",
"column": [
"\"ID1\"",
"\"NAME1\"",
"\"CREATE_TIME1\""
],
"connection": [
{
"table": [
"DATAX_TEST1"
],
"jdbcUrl": "jdbc:oracle:thin:@127.0.0.1:1521:orcl"
}
]
}
}
}
]
}
}