第1章 DataX部署
1.1 上传解压
1. 上传DataX的安装包到/opt/software下
[atguigu@hadoop102 software]$ ll
总用量 1406064
-rw-rw-r--. 1 atguigu atguigu 829372407 2月 27 12:00 datax.tar.gz
2. 解压Jar包到/opt/module/下
[atguigu@hadoop102 datax]$ tar -zxvf datax.tar.gz -C /opt/module
1.2 执行自检
1. 执行如下命令进行自检,出现如下内容表明安装成功。
[atguigu@hadoop102 datax]$ python bin/datax.py job/job.json
……
2022-02-27 12:52:15.568 [job-0] INFO JobContainer -
任务启动时刻 : 2022-02-27 12:52:05
任务结束时刻 : 2022-02-27 12:52:15
任务总计耗时 : 10s
任务平均流量 : 253.91KB/s
记录写入速度 : 10000rec/s
读出记录总数 : 100000
读写失败总数 : 0
第2章 DataX使用
2.1 DataX使用概述
2.1.1 DataX任务提交命令
DataX的使用非常简单,用户仅需要根据自己同步数据的数据源和目的地的类型来选择相应的Reader和Writer插件即可,并将Reader和Writer插件的信息配置在一个json文件中,然后,在执行命令时,指定配置文件提交数据同步任务即可。
任务提交实例:
[atguigu@hadoop102 datax]$ python bin/datax.py path/to/your/job.json
4.1.2 DataX配置文件格式
1. 可以执行如下命令,查看DataX配置文件模板
[atguigu@hadoop102 datax]$ python bin/datax.py -r mysqlreader -w hdfswriter
{
"job": { // 最外层时一个job, job包含setting和content两部分
"content": [ // content 用于配置用户的数据源和目的地
{
"reader": { // Reader相关配置
"name": "mysqlreader", // Reader名称(不可随意命名)
"parameter": { // Reader配置参数
"column": [],
"connection": [
{
"jdbcUrl": [],
"table": []
}
],
"password": "",
"username": "",
"where": ""
}
},
"writer": { // Writer相关配置
"name": "hdfswriter", // Writer 名称(不可随意命名)
"parameter": { // Writer 配置参数
"column": [],
"compress": "",
"defaultFS": "",
"fieldDelimiter": "",
"fileName": "",
"fileType": "",
"path": "",
"writeMode": ""
}
}
}
],
"setting": { // setting用于对整个job进行配置(限速等)。
"speed": {
"channel": ""
}
}
}
}
Reader和Writer的具体参数可参考官方文档:https://github.com/alibaba/DataX/blob/master/README.md
2.2 同步MySQl数据到HDFS案例
2.2.1 案例描述
1. 需求:同步gmall数据库中base_province表数据到HDFS的/base_province目录下。
2. 需求分析:
① 插件选择:MySQlReader和HDFSWriter两种
② 模式分类:TableMode和QuerySQLMode;
③ TableMode:使用table、column、where等属性声明需要同步的数据。
④ QuerySQLMode:后者使用一条SQL查询语句声明需要同步的数据。
3. 插件介绍:
① MysqlReader插件介绍:实现了从Mysql读取数据。在底层实现上,MysqlReader通过JDBC连接远程Mysql数据库,并执行相应的sql语句将数据从mysql库中select出来
② MysqlReader插件原理:MysqlReader通过JDBC连接器连接到远程的Mysql数据库,并根据用户配置的信息生成查询语句,然后发送到远程Mysql数据库,并将该SQL执行返回结果使用DataX自定义的数据类型拼装为抽象的数据集,并传递给下游Writer处理。TableMode模式中根据用户配置的Table、column、Where等信息生成SQl语句发送到Mysql数据库;QuerysqlMode模式则是直接将用户配置的querysql信息发送到Mysql数据库中。
③ HdfsWriter插件介绍:提供项HDFS文件系统指定路径中写入TextTile和OrcFile类型的文件,文件内容可与Hive表相关联。
④ HdfsWriter插件实现过程:首先根据用户指定的path,创建一个hdfs文件系统上的不存在的临时目录,创建规则是:path_随机;然后将读取的文件写入到这个临时目录中;待到全部写入后,再将这个临时目录下的文件移动到用户所指定的目录下,(在创建文件时保证文件名不重复);最后删除临时目录。如果在中见过程中发生网络中断等情况,造成无法与hdfs建立连接,需要用户手动删除已经写入的文件和临时目录。
接下来,我们分别使用两种模式进行演示
2.2.2 MySQLReader之TableMode
需求:同步gmall数据库中的base_province表数据中的id>3的数据到HDFS,
1. 边界配置文件:base_province_tableMode.json,编辑内容如下
{
"job": {
"content": [
{
"reader": {
"name": "mysqlreader",
"parameter": {
"column": ["id","name","region_id","area_code","iso_code","iso_3166_2"],
"connection": [
{
"jdbcUrl": ["jdbc:mysql://hadoop102:3306/gmall"],
"table": ["base_province"]
}
],
"password": "jianglai",
"username": "root",
"where": "id>=3",
"splitPk": ""
}
},
"writer": {
"name": "hdfswriter",
"parameter": {
"column": [
{"name": "id","type": "bigint"},
{"name": "name","type": "string"},
{"name": "region_id","type": "string"},
{"name": "area_code","type": "string"},
{"name": "iso_code","type": "string"},
{"name": "iso_3166_2","type": "string"}
],
"compress": "gzip",
"defaultFS": "hdfs://hadoop102:8020",
"fieldDelimiter": "\t",
"fileName": "base_province",
"fileType": "text",
"path": "/base_province",
"writeMode": "append"
}
}
}
],
"setting": {
"speed": {
"channel": "1"
}
}
}
}
2.参数说明
注意事项:
HDFS Writer并未提供nullFormat参数:也就是用户并不能自定义null值写到HDFS文件中的存储格式。默认情况下,HDFS Writer会将null值存储为空字符串(''),而Hive默认的null值存储格式为\N。所以后期将DataX同步的文件导入Hive表就会出现问题。
解决该问题的方案有两个:
①一是修改DataX HDFS Writer的源码,增加自定义null值存储格式的逻辑,可参考记Datax3.0解决MySQL抽数到HDFSNULL变为空字符的问题_datax nullformat_谭正强的博客-优快云博客。
② 二是在Hive中建表时指定null值存储格式为空字符串(''),例如:
DROP TABLE IF EXISTS base_province;
CREATE EXTERNAL TABLE base_province
(
`id` STRING COMMENT '编号',
`name` STRING COMMENT '省份名称',
`region_id` STRING COMMENT '地区ID',
`area_code` STRING COMMENT '地区编码',
`iso_code` STRING COMMENT '旧版ISO-3166-2编码,供可视化使用',
`iso_3166_2` STRING COMMENT '新版IOS-3166-2编码,供可视化使用'
) COMMENT '省份表'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
NULL DEFINED AS ''
LOCATION '/base_province/';
3. 提交任务
① 在HDFS创建/base_province目录
[atguigu@hadoop102 datax]$ hadoop fs -mkdir /base_province
② 进入DataX根目录
[atguigu@hadoop102 datax]$ pwd
/opt/module/datax
③ 执行如下命令
[atguigu@hadoop102 datax]$ python bin/datax.py job/base_province.json
4. 查看结果
① DataX打印日志
aitWriterTime 0.000s | All Task WaitReaderTime 0.000s | Percentage 100.00%
2022-02-28 00:36:18.684 [job-0] INFO JobContainer -
任务启动时刻 : 2022-02-28 00:36:07
任务结束时刻 : 2022-02-28 00:36:18
任务总计耗时 : 11s
任务平均流量 : 66B/s
记录写入速度 : 3rec/s
读出记录总数 : 32
读写失败总数 : 0
② 查看HDFS文件
[atguigu@hadoop102 datax]$ hadoop fs -cat /base_province/* | zcat
2022-02-28 00:38:26,344 INFO sasl.SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false
3 山西 1 140000 CN-14 CN-SX
4 内蒙古 1 150000 CN-15 CN-NM
5 河北 1 130000 CN-13 CN-HE
6 上海 2 310000 CN-31 CN-SH
7 江苏 2 320000 CN-32 CN-JS
8 浙江 2 330000 CN-33 CN-ZJ
9 安徽 2 340000 CN-34 CN-AH
10 福建 2 350000 CN-35 CN-FJ
11 江西 2 360000 CN-36 CN-JX
12 山东 2 370000 CN-37 CN-SD
14 台湾 2 710000 CN-71 CN-TW
15 黑龙江 3 230000 CN-23 CN-HL
16 吉林 3 220000 CN-22 CN-JL
17 辽宁 3 210000 CN-21 CN-LN
18 陕西 7 610000 CN-61 CN-SN
19 甘肃 7 620000 CN-62 CN-GS
20 青海 7 630000 CN-63 CN-QH
21 宁夏 7 640000 CN-64 CN-NX
22 新疆 7 650000 CN-65 CN-XJ
23 河南 4 410000 CN-41 CN-HA
24 湖北 4 420000 CN-42 CN-HB
25 湖南 4 430000 CN-43 CN-HN
26 广东 5 440000 CN-44 CN-GD
27 广西 5 450000 CN-45 CN-GX
28 海南 5 460000 CN-46 CN-HI
29 香港 5 810000 CN-91 CN-HK
30 澳门 5 820000 CN-92 CN-MO
31 四川 6 510000 CN-51 CN-SC
32 贵州 6 520000 CN-52 CN-GZ
33 云南 6 530000 CN-53 CN-YN
13 重庆 6 500000 CN-50 CN-CQ
34 西藏 6 540000 CN-54 CN-XZ
2.2.3 MySQLReader之QuerySQLMode
1. 在job目录下,编写配置文件base_province_querysqlmode.json内容如下
{
"job": {
"setting": {
"speed": {
"channel":1
}
},
"content": [
{
"reader": {
"name": "mysqlreader",
"parameter": {
"username": "root",
"password": "你的密码",
"connection": [
{
"querySql": [
"select id,name,region_id,area_code,iso_code,iso_3166_2 from base_province where id >=3;"
],
"jdbcUrl": [
"jdbc:mysql://hadoop102:3306/gmall"
]
}
]
}
},
"writer": {
"name": "hdfswriter",
"parameter": {
"column": [
{"name": "id","type": "bigint"},
{"name": "name","type": "string"},
{"name": "region_id","type": "string"},
{"name": "area_code","type": "string"},
{"name": "iso_code","type": "string"},
{"name": "iso_3166_2","type": "string"}
],
"compress": "gzip",
"defaultFS": "hdfs://hadoop102:8020",
"fieldDelimiter": "\t",
"fileName": "base_province",
"fileType": "text",
"path": "/base_province",
"writeMode": "append"
}
}
}
]
}
}
2. 参数说明
querySql:
在某些业务场景下,where这个配置项不足以描述所筛选的条件,用户可以通过该配置来自定义筛选SQL。当用户配置该项后,DataX系统就会忽略Table、column这些配置项,直接使用这个配置项的内容对数据进行筛选,例如需要进行多表join后同步数据的使用场景。
3. 提交任务
① 清空历史数据,就是在TableMode模式中同步到HDFS的base_province目录下的数据
[atguigu@hadoop102 datax]$ hadoop fs -rm -f /base_province/*
② 指定命令,执行同步
[atguigu@hadoop102 datax]$ python bin/datax.py job/base_province_querysqlmode.json.json
4. 查看结果
① DataX打印日志
aitWriterTime 0.000s | All Task WaitReaderTime 0.000s | Percentage 100.00%
2022-02-28 11:33:05.854 [job-0] INFO JobContainer -
任务启动时刻 : 2022-02-28 11:32:53
任务结束时刻 : 2022-02-28 11:33:05
任务总计耗时 : 12s
任务平均流量 : 66B/s
记录写入速度 : 3rec/s
读出记录总数 : 32
读写失败总数 : 0
② 查看HDFS文件
[atguigu@hadoop102 datax]$ hadoop fs -cat /base_province/*|zcat
2022-02-28 11:34:28,226 INFO sasl.SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false
3 山西 1 140000 CN-14 CN-SX
4 内蒙古 1 150000 CN-15 CN-NM
5 河北 1 130000 CN-13 CN-HE
6 上海 2 310000 CN-31 CN-SH
7 江苏 2 320000 CN-32 CN-JS
8 浙江 2 330000 CN-33 CN-ZJ
9 安徽 2 340000 CN-34 CN-AH
10 福建 2 350000 CN-35 CN-FJ
11 江西 2 360000 CN-36 CN-JX
12 山东 2 370000 CN-37 CN-SD
14 台湾 2 710000 CN-71 CN-TW
15 黑龙江 3 230000 CN-23 CN-HL
16 吉林 3 220000 CN-22 CN-JL
17 辽宁 3 210000 CN-21 CN-LN
18 陕西 7 610000 CN-61 CN-SN
19 甘肃 7 620000 CN-62 CN-GS
20 青海 7 630000 CN-63 CN-QH
21 宁夏 7 640000 CN-64 CN-NX
22 新疆 7 650000 CN-65 CN-XJ
23 河南 4 410000 CN-41 CN-HA
24 湖北 4 420000 CN-42 CN-HB
25 湖南 4 430000 CN-43 CN-HN
26 广东 5 440000 CN-44 CN-GD
27 广西 5 450000 CN-45 CN-GX
28 海南 5 460000 CN-46 CN-HI
29 香港 5 810000 CN-91 CN-HK
30 澳门 5 820000 CN-92 CN-MO
31 四川 6 510000 CN-51 CN-SC
32 贵州 6 520000 CN-52 CN-GZ
33 云南 6 530000 CN-53 CN-YN
13 重庆 6 500000 CN-50 CN-CQ
34 西藏 6 540000 CN-54 CN-XZ
2.2.4 DataX之传参
1. 什么时传参,为什么传参?
在生产环境中,离线数据同步任务需要每日定时重复执行,故HDFS上的目标路径通常会包含一层日期,用来对每日同步的数据加以分区,也就是说每日同步数据的目标路径不是固定的,因此DataX配置文件中的DHFSWriter插件中参数path的值应该是动态变化的。为实现这个业务需求,我们需要使用DataX的传参功能
2. DataX传参用法
① 首选在任务的json配置文件中使用${param}引用参数
② 然后在提交任务时使用-p "-Dparam=value" 传入参数值
3. 传参案例操作
① 以QuerySqlMode模式为例,修改配置文件base_province_querysqlmode.json
……
"writer": {
"name": "hdfswriter",
"parameter": {
"column": [
{"name": "id","type": "bigint"},
{"name": "name","type": "string"},
{"name": "region_id","type": "string"},
{"name": "area_code","type": "string"},
{"name": "iso_code","type": "string"},
{"name": "iso_3166_2","type": "string"}
],
"compress": "gzip",
"defaultFS": "hdfs://hadoop102:8020",
"fieldDelimiter": "\t",
"fileName": "base_province",
"fileType": "text",
"path": "/base_province/${dt}",
"writeMode": "append"
}
}
……
② 在HDFS文件系统中创建目录
[atguigu@hadoop102 datax]$ hadoop fs -mkdir /base_province/2022_03_18
③ 进入DataX目录下,执行命令开始同步任务
[atguigu@hadoop102 datax]$ python bin/datax.py -p "-Ddt=2022_03_18" job/base_province_querysqlmode.json
4. 查看结果
① DataX日志
aitWriterTime 0.000s | All Task WaitReaderTime 0.000s | Percentage 100.00%
2022-02-28 12:20:53.762 [job-0] INFO JobContainer -
任务启动时刻 : 2022-02-28 12:20:42
任务结束时刻 : 2022-02-28 12:20:53
任务总计耗时 : 11s
任务平均流量 : 66B/s
记录写入速度 : 3rec/s
读出记录总数 : 32
读写失败总数 : 0
② HDFS目录文件
[atguigu@hadoop102 datax]$ hadoop fs -ls /base_province/2022_03_18
Found 1 items
-rw-r--r-- 3 atguigu supergroup 532 2022-02-28 12:22 /base_province/2022_03_18/base_province__5eaa29df_a3f3_4ccc_8087_e96688eb1f1b.gz
2.3 同步HDFS数据到MySQL案例
2.3.1 案例描述
1. 案例需求:同步DHFS上的base_province目录下的数据到Mysql中gmall数据库的test_province表
2. 需求分析:要实现上述业务需求,需要使用HDFSReader和MySQLWriter插件
3. 插件介绍
① HdfsReader插件介绍:提供了读取分布式文件系统数据存储的能力。在底层实现上,HdfsReader获取分布式文件系统上文件的数据,并转换为DataX传输协议传递给Writer,支持textfile、orcfile、rcfile、sequencefile。
② MysqlWriter插件介绍:实现了写入数据到Mysql数据库目的表的功能。在底层实现上,MysqlWriter通过JDBC连接远程的Mysql数据库,并执行相应的inster into … 或者 replace into 的sql语句,将数据写入到Mysql,内部会分批次提交入库,需要数据库本身采用innodb引擎。
③ MysqlWriter实现原理:MysqlWriter通过DataX框架获取Reader生成的协议数据,根据你配置的writeMode生成相应的插入模式。
·Insert:当主键/唯一性索引冲突时,不会写入冲突的行;
·replace :当主键/唯一性索引不冲突时,与insert行为一致,当遇见冲突时,会更新替换原有的行(字段)。
·update:当主键/唯一性索引不冲突时,与insert行为一致,当遇见冲突时,会更新更新原有的行(字段)。
4. 案例实操
① 编写配置文件base_province_hdfs2mysql.json
{
"job": {
"setting": {
"speed": {
"channel": 1
}
},
"content": [
{
"reader": {
"name": "hdfsreader",
"parameter": {
"path": "/base_province",
"defaultFS": "hdfs://hadoop102:8020",
"column": ["*"],
"fileType": "text",
"compress": "gzip",
"encoding": "UTF-8",
"nullFormat": "\\N",
"fieldDelimiter": "\t"
}
},
"writer": {
"name": "mysqlwriter",
"parameter": {
"writeMode": "replace",
"username": "root",
"password": "你的密码",
"column": [
"id",
"name",
"region_id",
"area_code",
"iso_code",
"iso_3166_2"
],
"connection": [
{
"jdbcUrl": "jdbc:mysql://hadoop102:3306/gmall?useUnicode=true&characterEncoding=utf-8",
"table": [
"test_province"
]
}
]
}
}
}
]
}
}
② 参数说明
③ 在mysql中创建gmall.test_province表
DROP TABLE IF EXISTS `test_province`;
CREATE TABLE `test_province` (
`id` bigint(20) NOT NULL,
`name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`region_id` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`area_code` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`iso_code` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`iso_3166_2` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
④ 提交执行同步任务
[atguigu@hadoop102 datax]$ python bin/datax.py job/base_province_hdfs2mysql.json
⑤ 查看结果
DataX日志
WaitWriterTime 0.000s | All Task WaitReaderTime 0.026s | Percentage 100.00%
2022-02-28 13:36:53.549 [job-0] INFO JobContainer -
任务启动时刻 : 2022-02-28 13:36:41
任务结束时刻 : 2022-02-28 13:36:53
任务总计耗时 : 11s
任务平均流量 : 133B/s
记录写入速度 : 6rec/s
读出记录总数 : 64
读写失败总数 : 0
查看test_province表中数据
mysql> select * from test_province limit 10;
+------+-----------+-----------+-----------+----------+------------+
| id | name | region_id | area_code | iso_code | iso_3166_2 |
+------+-----------+-----------+-----------+----------+------------+
| 3 | 山西 | 1 | 140000 | CN-14 | CN-SX |
| 4 | 内蒙古 | 1 | 150000 | CN-15 | CN-NM |
| 5 | 河北 | 1 | 130000 | CN-13 | CN-HE |
| 6 | 上海 | 2 | 310000 | CN-31 | CN-SH |
| 7 | 江苏 | 2 | 320000 | CN-32 | CN-JS |
| 8 | 浙江 | 2 | 330000 | CN-33 | CN-ZJ |
| 9 | 安徽 | 2 | 340000 | CN-34 | CN-AH |
| 10 | 福建 | 2 | 350000 | CN-35 | CN-FJ |
| 11 | 江西 | 2 | 360000 | CN-36 | CN-JX |
| 12 | 山东 | 2 | 370000 | CN-37 | CN-SD |
+------+-----------+-----------+-----------+----------+------------+
10 rows in set (0.00 sec)
第3章 DataX优化
3.1 速度控制
1. 速度控制介绍
DataX中提供了包括通道(并发)、记录流、字节流三种流控模式,可以根据需要控制你的作业速度,让你的作业在数据库可以承受的范围内达到最佳的同步速度。
2. 优化参数
参数 | 说明 | 注意事项 |
job.setting.speed.channel | 并发数 | |
job.setting.speed.record | 总record限速 | 配置此参数,则必须配置单个channel的record限速参数 |
job.setting.speed.byte | 总byte限速 | 配置此参数,则必须配置单个channel的byte限速参数 |
core.transport.channel.speed.record | 单个channel的record限速,默认10000条/s | |
core.transport.channel.speed.byte | 单个channel的byte限速,默认1M/s |
注意:如果配置了总record限速和总byte限速,channel并发数就会失效。因为配置了这两个参数后,实际的channel并发数是通过计算得到的
①计算公式:
② 配置实例:
{
"core": {
"transport": {
"channel": {
"speed": {
"byte": 1048576 //单个channel byte限速1M/s
}
}
}
},
"job": {
"setting": {
"speed": {
"byte" : 5242880 //总byte限速5M/s
}
},
...
}
}
3.2 内存调整
1. 内存调整介绍
当提升DataX Job内的Channel并发数时,内存的占用会明显增加,因为DataX作为数据交换通道,在内存中会缓存较多的数据,例如:channel中会有一个Buffer,作为临时的数据交换缓冲区,而在Reader和Write中,也会有一些buffer,为了防止OOM等错误,需要适当调大JVM堆内存。
2. 建议措施
建议根据实际情况来适当调整内存,如:将内存设置为4G或者8G,
方式:
① 修改datax.py脚本
② 启动时使用参数:python bin/datax.py --jvm = "-Xms8G -Xmx8G” /path/to/your/job.json