DataX 3.0是阿里云DataWorks数据集成的开源版本,可以方便的对各种异构数据源进行高效的数据同步。其github地址为:
https://github.com/alibaba/DataXhttps://github.com/alibaba/DataX
DataX将复杂的网状的同步链路变成了星型数据链路,DataX自身作为中间传输载体负责连接各种数据源,友好的解决了异构数据源同步问题。DataX采用Framework+plugin架构构建,将数据源读取和写入抽象成为Reader/Writer插件,纳入到整个同步框架中:
Reader:Reader为数据采集模块,负责采集数据源的数据,将数据发送给Framework。
Writer:Writer为数据写入模块,负责不断向Framework取数据,并将数据写入到目的端。
Framework:Framework用于连接reader和writer,作为两者的数据传输通道,并处理缓冲,流控,并发,数据转换等核心技术问题。
考虑到DataX的易用性和扩展性,StarRocks单独开发了StarRocksWriter插件。在底层实现上,StarRocksWriter内部将各种reader读取的数据进行缓存攒批(以csv或json格式),然后仍旧通过Stream load方式导入至StarRocks,总体数据流是source -> Reader -> DataX channel -> Writer -> StarRocks。
编译好的StarRocksWriter的github下载地址为:
Tags · StarRocks/DataX · GitHubhttps://github.com/StarRocks/DataX/tags
下载后将其解压至DataX的datax/plugin/writer路径下。
注意,StarRocksWriter目前只适配了DataX,可能不支持其他基于DataX的三方产品。目前github上阿里编译好的DataX打包的有点问题,大家可以使用源码自己编译或者下载评论区百度云里我编译好的(已添加StarRocksWriter)。
StarRocks官网对DataX的操作也做了详细的介绍,文档地址为:
https://docs.starrocks.com/zh-cn/main/loading/DataX-starrocks-writerhttps://docs.starrocks.com/zh-cn/main/loading/DataX-starrocks-writer
DataX的运行环境要求JDK(1.8以上,推荐1.8)及Python(2或3都可以),其使用更是简单,只需要参考模板编写一个数据同步任务的json文件,然后指定json执行DataX即可。为方便演示,我们还先建表并准备数据,以同步MySQL中的数据到StarRocks为例,演示所用的架构如下:
节点IP |
部署服务 |
端口 |
版本 |
说明 |
192.168.110.101 [node01] |
FE |
9030 |
2.0.0-GA |
query_port |
BE |
用户名密码均为root |
|||
Broker |
Broker名称:hdfs_broker |
|||
mysql-client |
5.7.36 |
|||
DataX |
/opt/module/datax |
|||
192.168.110.102 [node02] |
MySQL Community Server |
5.7.36 |
用户名密码均为root |
在MySQL中创建演示表:
[root@node02 ~]# mysql -uroot -proot
mysql> create database ODS;
mysql> use ODS;
mysql> CREATE TABLE `departments` (
`department_id` int(4) NOT NULL AUTO_INCREMENT,
`department_name` varchar(3) DEFAULT NULL,
`manager_id` int(6) DEFAULT NULL,
`location_id` int(4) DEFAULT NULL,
PRIMARY KEY (`department_id`)
);
插入演示数据:
mysql> insert into `departments`(`department_id`,`department_name`,`manager_id`,`location_id`) values (10,'Adm',200,1700),(20,'Mar',201,1800),(30,'Pur',114,1700),(40,'Hum',203,2400),(50,'Shi',121,1500),(60,'IT',103,1400),(70,'Pub',204,2700),(80,'Sal',145,2500),(90,'Exe',100,1700),(100,'Fin',108,1700),(110,'Acc',205,1700),(120,'Tre',NULL,1700),(130,'Cor',NULL,1700),(140,'Con',NULL,1700),(150,'Sha',NULL,1700),(160,'Ben',NULL,1700),(170,'Man',NULL,1700),(180,'Con',NULL,1700),(190,'Con',NULL,1700),(200,'Ope',NULL,1700),(210,'IT ',NULL,1700),(220,'NOC',NULL,1700),(230,'IT ',NULL,1700),(240,'Gov',NULL,1700),(250,'Ret',NULL,1700),(260,'Rec',NULL,1700),(270,'Pay',NULL,1700);
DataX只能同步数据,不能同步表结构,所以在执行任务前,我们需要先在目标数据库中手动创建好表。
StarRocks中建表:
[root@node01 ~]# mysql -h192.168.110.101 -P9030 -uroot –proot
mysql> create database starrocks;
mysql> use starrocks;
mysql> CREATE TABLE `departments` (
`department_id` int NOT NULL,
`department_name` varchar(30) DEFAULT NULL,
`manager_id` int DEFAULT NULL,
`location_id` int DEFAULT NULL
)
DUPLICATE KEY(department_id)
DISTRIBUTED BY HASH (department_id) BUCKETS 10
PROPERTIES (
"replication_num"="1");
如果有varchar(n)类型的列,注意StarRocks中varchar(n)的n为字节数。
DataX中的任务配置文件是json格式,我们可以方便的通过下面的命令查看内置的任务配置模板:
python datax.py -r {YOUR_READER} -w {YOUR_WRITER}
这里我们就可以写为:
[root@node01 datax]# python bin/datax.py -r mysqlreader -w starrockswriter
根据模板,编写我们的作业文件:
[root@node01 datax]# vi job/mysql2starrocks.json
输入:
{
"job": {
"setting": {
"speed": {
"channel": 1
},
"errorLimit": {
"record": 0,
"percentage": 0
}
},
"content": [
{
"reader": {
"name": "mysqlreader",
"parameter": {
"username": "root",
"password": "root",
"column": [ "*" ],
"splitPk": "department_id",
"connection": [
{
"table": [ "departments" ],
"jdbcUrl": [
"jdbc:mysql://192.168.110.102:3306/ODS"
]
}
]
}
},
"writer": {
"name": "starrockswriter",
"parameter": {
"username": "root",
"password": "root",
"database": "starrocks",
"table": "departments",
"column": [ "*" ],
"preSql": [],
"postSql": [],
"jdbcUrl": "jdbc:mysql://192.168.110.101:9030/",
"loadUrl": ["192.168.110.101:8030"],
"loadProps": {}
}
}
}
]
}
}
关于mysqlreader部分,可以在DataX的文档中看到详细的参数(使用其他数据库的reader或writer时,也可以在这里查看相关参数的介绍):
主要参数介绍如下:
1、Password
描述:StarRocks数据库的密码。
必选:是(密码不能为空)
默认值:无
2、loadUrl
描述:StarRocks FE的地址用于Streamload,可以为多个fe地址,形如fe_ip:fe_http_port,例如["192.168.110.101:8030", "192.168.110.102:8030"]。
必选:是
默认值:无
3、column
描述:目的表需要写入数据的字段,字段之间用英文逗号分隔。例如: "column": ["id","name","age"]。column配置项必须指定,不能留空!如果希望导入所有字段,可以使用["*"]。
必选:是
默认值:无
4、preSql
描述:写入数据到目的表前,会先执行这里的标准语句。
必选:否
默认值:无
5、postSql
描述:写入数据到目的表后,会执行这里的标准语句。
必选:否
默认值:无
6、jdbcUrl
描述:目的数据库的JDBC连接信息,用于执行preSql及postSql。
必选:否
默认值:无
7、maxBatchRows
描述:单次StreamLoad导入的最大行数。与下面的两个参数maxBatchSize、flushInterval是“或”的关系,当攒批的数据条数、数据大小或攒批时间其中一个达到参数设置值后结束本次攒批执行导入。
必选:否
默认值:500000(50W)
8、maxBatchSize
描述:单次StreamLoad导入的最大字节数。
必选:否
默认值:104857600(100M)
9、flushInterval
描述:上一次StreamLoad结束至下一次开始的时间间隔(单位:ms)。
必选:否
默认值:300000(ms)
10、loadProps
描述:StreamLoad的请求参数,详情参照StreamLoad介绍章节。
必选:否
默认值:无
这里以我们经常使用的行列分隔符为例,在StarRocksWriter中,默认传入的数据均会被转为字符串,并以\t作为列分隔符,\n作为行分隔符,组成csv文件进行StreamLoad导入操作。如果默认的分隔符与我们的数据冲突,也可以通过loadProps使用Stream Load中的参数自定义列分隔符,例如:
"loadProps": {
"column_separator": "\\x01",
"row_delimiter": "\\x02"
}
当数据质量较差,不好确认分隔符时,我们也可以配置攒批数据的数据格式为json,来规避分隔符的问题:
"loadProps": {
"format": "json",
"strip_outer_array": true
}
[root@node01 datax]# python bin/datax.py job/mysql2starrocks.json
DataX在运行日志中打印了大量信息,其中包括传输速度,Reader、Writer性能,进程CPU,JVM和GC情况等等。
任务完成后,打印总体运行情况:
2022-01-15 23:19:15.611 [job-0] INFO JobContainer -
任务启动时刻 : 2022-01-15 23:19:04
任务结束时刻 : 2022-01-15 23:19:15
任务总计耗时 : 9s
任务平均流量 : 29B/s
记录写入速度 : 2rec/s
读出记录总数 : 27
读写失败总数 : 0
如果任务失败,也会在控制台打印可能的失败原因。
当任务失败时,我们可以在作业执行命令后加上--loglevel=debug来查看更详细的响应日志,例如:
[root@node01 datax]# python bin/datax.py job/mysql2starrocks.json --loglevel=debug
如果是数据问题,我们也可以利用streamwriter将数据读取后打印到控制台来定位问题,例如我们还简单编写一个作业文件:
[root@node01 datax]# vi job/mysql2stream.json
{
"job": {
"setting": {
"speed": {
"channel": 1
},
"errorLimit": {
"record": 0,
"percentage": 0
}
},
"content": [
{
"reader": {
"name": "mysqlreader",
"parameter": {
"username": "root",
"password": "root",
"column": [ "*" ],
"splitPk": "department_id",
"connection": [
{
"table": [ "departments" ],
"jdbcUrl": [
"jdbc:mysql://192.168.110.102:3306/ODS"
]
}
]
}
},
"writer": {
"name": "streamwriter",
"parameter": {
"encoding": "UTF-8",
"print": true
}
}
}
]
}
}
启动DataX,执行作业,即可在控制台看到从Reader中读到的数据:
[root@node01 datax]# python bin/datax.py job/mysql2stream.json
若我们在数据导入过程中发现导入目标表的时间戳类数据与源库数据相差8小时,则可以检查数据源和目标库的时区是否一致,或者我们也可以在datax.py启动脚本中添加时区参数,例如添加GMT+8时区:
[root@node01 datax]# vi bin/datax.py
DEFAULT_PROPERTY_CONF中添加:-Duser.timezone=GMT+8
1、合理拆分任务
合理配置任务参数,让DataX任务拆分为多个Task,同时,提升DataX Channel并发数。以mysqlreader为例,就要合理配置splitPk参数,如果splitPk不填写(包括不提供splitPk或者splitPk值为空),DataX会视作使用单通道同步该表数据。
2、配置堆内存
当提升DataX Job内Channel并发数时,内存的占用会显著增加,因为DataX作为数据交换通道,在内存中会缓存较多的数据。例如Channel中会有一个Buffer,作为临时的数据交换的缓冲区,而在部分Reader和Writer的中,也会存在一些Buffer,为了防止OOM等错误,调大JVM的堆内存。通常建议将内存设置为4G或者8G,这个也可以根据实际情况来调整。
调整JVM xms xmx参数的两种方式:一种是直接更改datax.py脚本;另一种是在启动的时候,加上对应的参数,如下:
python datax/bin/datax.py --jvm="-Xms8G -Xmx8G" XXX.json
建议将初始化堆内存与堆最大内存配置的一致,这样可以让同步数据处理起来更快,也可以避免内存的抖动。
使用DataX进行数据同步的另一个优势是可以限速,进而降低同步过程中对业务库的压力影响。DataX3.0提供了包括通道(并发)、记录流、字节流三种流控模式,可以方便的控制同步作业速度,让同步作业在库可以承受的范围内达到最佳的同步速度。以最常用的字节流限速为例:
修改datax/conf/core.json,限制单个chanel的速度为2M:
"speed": {
"byte": 2097152,
},
同时修改咱们作业json部分的速度限制,例如限制为4M(这样任务会用4/2=2个channel并发进行任务),修改:
"job": {
"setting": {
"speed": {
"byte" : 4194304
}
},
...
}
以及:
"speed": {
"channel": 5,
"byte": 1048576,
"record": 10000
}
StarRocks兼容MySQL协议,当我们需要将StarRocks中的数据同步至其他数据库时,也可以使用mysqlreader来直接读取,但这种JDBC的方式性能可能不是很好,还是推荐官方的Flink Connector或者Spark Connector来进行处理。