2021-12-28 迈向程序猿的第五十六步

目录

一、sqoop的高阶用法

1.1 增量导入

1.1.1 增量和全量的概念

1.1.2 增量导入的方式

1.1.3 案例演示

1.2 job的应用

1.2.1 job的优点

1.2.2 job的参数

1.2.3 案例演示1

1.2.4 案例演示2

1.3 metastore的应用

1.3.1 metastore的介绍

1.3.2 配置metastore服务项

1.3.3 案例演示1

1.3.4 案例演示2

1.4 sqoop的优化

二、DataX概述

2.1 DataX简介

2.3 DataX3.0插件体系

 2.4 DataX3.0核心架构

2.5 六大核心优势

三、DataX的快速入门

3.1 环境需求

3.2 安装方式

方法1 直接下载DataX工具包

方法2 下载DataX源码,自己编译(不推荐)

3.3 查看常用的Reader和Writer插件样本

四、案例演示

4.1 Stream->Stream

4.2 mysql -> hdfs

4.3 mysql->hive

4.4 hdfs -> mysql

4.5 hive->mysql

4.6 增量导入

五、DataX调优方案


一、sqoop的高阶用法

1.1 增量导入

1.1.1 增量和全量的概念

在实际生产环境中,数据要源源不断的导入到数据仓库中进行分析。而增量导入是必须的,也可以避免很多重复的数据出现。
增量导入的概念:就是将数据源的新数据(旧数据已经导入过)导入到hadoop生态系统中。
         订单表  :   订单号,商品ID,用户ID,时间
全量导入: 当数据变化的量相对较少时,可以重新覆盖导入。
         用户信息表
         商品信息表
         店铺信息

1.1.2 增量导入的方式

增量导入的方式有三种

1.  使用通用参数:--append
2.  使用-e|--query,指定条件进行增量导入
3.  使用--incremental 和 --last-value  --check-column 组合进行增量导入
       --incremental  用来指定导入模式, append|lastmodified
       --last-value   记录上一次导入的最大值,表示这一次从这个值开始导入
       --check-column 用于指定要检查的字段。

1.1.3 案例演示

1)使用--query方式增量导入到hive中

# 假如昨天导入的数据是10和20号部门的数据,如下:
[root@xxx01 ~]# sqoop import \
--connect jdbc:mysql://xxx03:3306/sz2103 \
--username root \
--password @Mmforu45 \
-e "select * from emp where \$CONDITIONS and deptno in(10,20)" \
--split-by "empno" \
--target-dir "/temp/emp" \
--delete-target-dir \
--hive-import \
--hive-table "sz2103.emp_inrem" \
--fields-terminated-by "\t" \
-m 2
​
​
#今天导入新增加的30号部门的数据
​
[root@xxx01 ~]# sqoop import \
--connect jdbc:mysql://xxx03:3306/sz2103 \
--username root \
--password @Mmforu45 \
-e "select * from emp where \$CONDITIONS and deptno in(30)" \
--split-by "empno" \
--target-dir "/temp/emp" \
--delete-target-dir \
--hive-import \
--hive-table "sz2103.emp_inrem" \
--fields-terminated-by "\t" \
-m 2

2) 测试通用参数--append

小贴士:想要增量导入,就不能使用--delete-target-dir ,需要使用--append参数向hdfs上追加数据

如果不指定--append参数,会报目录已经存在。

# 模拟昨天的数据:
[root@xxx01 ~]# sqoop import \
--connect jdbc:mysql://xxx03:3306/sz2103 \
--username root \
--password @Mmforu45 \
--table emp \
--target-dir "/sqoop/emp_increm" \
--delete-target-dir \
--fields-terminated-by "\t" \
--where "deptno=10 or deptno = 20" \
-m 1
​
​
# 进行增量导入30号部门的数据
[root@xxx01 ~]# sqoop import \
--connect jdbc:mysql://xxx03:3306/sz2103 \
--username root \
--password @Mmforu45 \
--append \
--table emp \
--target-dir "/sqoop/emp_increm" \
--fields-terminated-by "\t" \
--where "deptno=30" \
-m 1

3)测试incremental,向hdfs上增量导入数据

--last-value: 从指定的值开始检查,如果有大于此值的数据,就认为是新数据,才会增量导入。导入后,会记录这次导入的最大值,为下一次增量导入做提示。

--check-column: 检查指定列,是否有新值,那么从意义上来说,指定的列应该具有唯一,非空,自增的特点。

# 模拟昨天的数据:
[root@xxx01 ~]# sqoop import \
--connect jdbc:mysql://xxx03:3306/sz2103 \
--username root \
--password @Mmforu45 \
--table emp \
--target-dir "/sqoop/emp_hdfs" \
--delete-target-dir \
--fields-terminated-by "\t" \
--where "empno<7700" \
-m 1
​
# 增量导入
[root@xxx01 ~]# sqoop import \
--connect jdbc:mysql://xxx03:3306/sz2103 \
--username root \
--password @Mmforu45 \
--table emp \
--target-dir "/sqoop/emp_hdfs" \
--fields-terminated-by "\t" \
--incremental append \
--last-value 7700 \
--check-column "empno" \
-m 1
​
​
注意:增量导入时,不要有--delete-target-dir参数

小贴士:

如果last-value的值由人来维护,那么很可能出现重复数据,人指定的值可能会出错,所以应该使用一种机制来自动维护last-value的值。

1.2 job的应用

1.2.1 job的优点

--1. 可以将导入导出语句创建到job里,然后可以重复的执行job。避免重写一堆参数,也可以使用定时器来定时执行job
--2. 如果job里封装了增量导入语句,由于job里自动维护了一堆参数,包括--last-value,因此执行job后,job会记录last-value的最新的值,以便下次导入新的行数据。
--3. 基于要维护last-value这样的值,因此涉及到元数据的存储。默认是存储到$HOME/.sqoop/下,但是不安全,因此也可以维护到mysql里。

1.2.2 job的参数

[root@xxx01 ~]# sqoop job --help
[root@xxx01 ~]# sqoop help job
usage: sqoop job [GENERIC-ARGS] [JOB-ARGS] [-- [<tool-name>] [TOOL-ARGS]]
​
Job management arguments:
   --create <job-id>            Create a new saved job
   --delete <job-id>            Delete a saved job
   --exec <job-id>              Run a saved job
   --help                       Print usage instructions
   --list                       List saved jobs
   --meta-connect <jdbc-uri>    Specify JDBC connect string for the
                                metastore
   --show <job-id>              Show the parameters for a saved job
   --verbose                    Print more information while working

1.2.3 案例演示1

1)创建一个job,相当于将导入语句封装到job里。可以通过执行job来进行导入功能

[root@xxx01 ~]# sqoop job --create job1 \
-- import \
--connect jdbc:mysql://xxx03:3306/sz2103 \
--username root \
--password @Mmforu45 \
--table emp \
--target-dir "/sqoop/emp_job" \
--delete-target-dir \
--fields-terminated-by "\t" \
--where "empno<7700" \
-m 1

注意事项:

--1. 创建job时,一定要添加import参数,而且要与前面的--之间有一个空格

–2. 如果报以下错误:

ERROR sqoop.Sqoop: Got exception running Sqoop: java.lang.NullPointerException java.lang.NullPointerException

at org.json.JSONObject.<init>(JSONObject.java:144)

需要将java-json.jar包导入到sqoop的lib目录下

–3. 如果第一次创建时,失败的话,可能会产生jobid. 需要删除后再执行

2)查询所有的job

[root@xxx01 ~]# sqoop job --list

3)执行job

小贴士:会提示输入mysql的密码, 虽然job里有密码。

[root@xxx01 ~]# sqoop job --exec job1

4)写一个定时脚本执行,规定中午12点整和半夜12整执行

[root@xxx01 ~]# crontab -e
0 12,0 * * * /usr/local/sqoop/bin/sqoop job --exec job1

1.2.4 案例演示2

1)创建一个带有增量导入的job

[root@xxx01 ~]# sqoop job \
--create job2 \
-- import \
--connect jdbc:mysql://xxx03:3306/sz2103 \
--username root \
--password @Mmforu45 \
--table emp \
--target-dir "/sqoop/emp_hdfs" \
--fields-terminated-by "\t" \
--incremental append \
--check-column "empno" \
-m 1

2) 查看指定job

[root@xxx01 ~]# sqoop job --show job2

3)执行job

[root@xxx01 ~]# sqoop job --exec job2

4)在mysql的emp表中插入三条新记录

insert into emp (empno,ename,job,deptno) values (10001,'zhangsan','clerk',10);
insert into emp (empno,ename,job,deptno) values (10002,'lisi','clerk',10);
insert into emp (empno,ename,job,deptno) values (10003,'wangwu','clerk',10);

5)再次执行job2

[root@xxx01 ~]# sqoop job --exec job2

会看到之导入了大于10000的三条记录。last-value变成了10003

1.3 metastore的应用

1.3.1 metastore的介绍

1. metastore服务是sqoop的元数据服务,用于存储sqoop的job相关信息
2. 默认会使用内嵌的元数据库,存储位置位于~/.sqoop/下
3. 由于安全性问题,将job信息保存于关系型数据库中是最合适的,关系型数据库可以选择mysql

1.3.2 配置metastore服务项

步骤1)修改用户自定义配置文件

[root@xxx01 conf]# vim sqoop-site.xml
<configuration>
    <!-- 是否要启动客户端自动连接元数据库 -->
    <property>
        <name>sqoop.metastore.client.enable.autoconnect</name>
        <value>true</value>
    </property>
     <!-- 连接元数据库的url -->
    <property>
        <name>sqoop.metastore.client.autoconnect.url</name>
        <value>jdbc:mysql://xxx03:3306/sqoop</value>
    </property>
    <!-- 连接元数据库的username -->
    <property>
        <name>sqoop.metastore.client.autoconnect.username</name>
        <value>root</value>
    </property>
    <!-- 连接元数据库的密码 -->
    <property>
        <name>sqoop.metastore.client.autoconnect.password</name>
        <value>@Mmforu45</value>
    </property>
     <!-- 是否要记住密码 -->
    <property>
        <name>sqoop.metastore.client.record.password</name>
        <value>true</value>
    </property>
    <property>
        <name>sqoop.metastore.server.location</name>
        <value>/usr/local/sqoop/sqoop-metastore/shared.db</value>
    </property>
    <property>
        <name>sqoop.metastore.server.port</name>
        <value>16000</value>
    </property>
</configuration>    

步骤2)在mysql中创建sqoop数据库

mysql> create database sqoop;

步骤3)启动sqoop的服务项

[root@xxx01 ~]# sqoop metastore
或者后台启动
[root@xxx01 ~]# nohup sqoop metastore &

步骤4)在sqoop库中要维护一张表SQOOP_ROOT

#方式1:可以使用sqoop的某一个语句进行连接,这样就可以创建此表
​
执行如下语句即可
sqoop job --list --meta-connect 'jdbc:mysql://xxx03:3306/sqoop?user=root&password=@Mmforu45'
​
执行后,SQOOP_ROOT表创建成功,  有可能报错,但是表会创建成功。
​
​
​
#方式2)手动维护此表
CREATE TABLE `SQOOP_ROOT` (
  `version` int(11) DEFAULT NULL,
  `propname` varchar(128) NOT NULL,
  `propval` varchar(256) DEFAULT NULL,
  UNIQUE KEY `SQOOP_ROOT_unq` (`version`,`propname`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

步骤5)需要向SQOOP_ROOT中添加一条记录

insert into SQOOP_ROOT values (NULL, 'sqoop.hsqldb.job.storage.version', '0');

步骤6)修改两张表的存储引擎为myisam(innoDB引擎会引起事务锁超时情况)

alter table SQOOP_ROOT engine=myisam;
​
​
​
alter table SQOOP_SESSIONS engine=myisam;
​
如果执行上述语句时,报错,那么就再次执行一次:
sqoop job --list --meta-connect 'jdbc:mysql://xxx03:3306/sqoop?user=root&password=@Mmforu45'
然后再修改存储引擎

1.3.3 案例演示1

1)创建一个job

[root@xxx01 ~]# sqoop job --create job1 \
-- import \
--connect jdbc:mysql://xxx03:3306/sz2103 \
--username root \
--password @Mmforu45 \
--table emp \
--target-dir "/sqoop/emp_job" \
--delete-target-dir \
--fields-terminated-by "\t" \
--where "empno<7700" \
-m 1

2)查询metastore里保存的job

sqoop job --list \
--meta-connect 'jdbc:mysql://xxx03:3306/sqoop?user=root&password=@Mmforu45' 

小贴士:由于sqoop-site.xml里的自动连接属性为true,所以可以不添加--meta-connect参数

3)执行metastore里保存的job

[root@xxx01 ~]# sqoop job --exec job1

1.3.4 案例演示2

1)创建增量导入的job

[root@xxx01 ~]# sqoop job --create job2 \
-- import \
--connect jdbc:mysql://xxx03:3306/sz2103 \
--username root \
--password @Mmforu45 \
--table emp \
--target-dir "/sqoop/emp_me" \
--fields-terminated-by "\t" \
--incremental append \
--check-column "empno" \
-m 1

注意:第一次创建增量job时,last-value参数可以不指定,默认导入全表的数据,然后会自动维护last-value的值

2)执行

sqoop job --exec job2

注意:想要使用metastore保存增量导入的job,那么SQOOP_SESSIONS的存储引擎必须是myisam。否则在执行job,想要保存last-value时,会失败

3)在mysql的emp表中插入两条新数据

insert into emp (empno,ename,job,deptno) values (10004,'lisi','clerk',10);
insert into emp (empno,ename,job,deptno) values (10005,'wangwu','clerk',10);

4)再次执行job2

sqoop job --exec job2

验证方式:

1. 可以查看hdfs上的目录的数据文件是否新增
2. 可以去mysql的sqoop库下查看SQOOP_SESSIONS里的数据

1.4 sqoop的优化

-1. mapTask的数量不能超过yarn的Vcore的数目,默认情况下yarn的VCORE的数量是8
-2. 如果数据量比较小,在200M以内,建议使用一个MapTask
-3. split-by指定的字段最好是均分分布的数字类型或者是时间类型。
-4. --fetch-size的数目的数据总大小最好在128M以内。      

二、DataX概述

2.1 DataX简介

DataX 是一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。

设计理念

为了解决异构数据源同步问题,DataX将复杂的网状的同步链路变成了星型数据链路,DataX作为中间传输载体负责连接各种数据源。当需要接入一个新的数据源的时候,只需要将此数据源对接到DataX,便能跟已有的数据源做到无缝数据同步。

当前使用现状

DataX在阿里巴巴集团内被广泛使用,承担了所有大数据的离线同步业务,并已持续稳定运行了6年之久。目前每天完成同步8w多道作业,每日传输数据量超过300TB。

此前已经开源DataX1.0版本,此次介绍为阿里云开源全新版本DataX3.0,有了更多更强大的功能和更好的使用体验。

Github主页地址:GitHub - alibaba/DataX: DataX是阿里云DataWorks数据集成的开源版本。

2.2 DataX的框架设计

DataX本身作为离线数据同步框架,采用Framework + plugin架构构建。将数据源读取和写入抽象成为Reader/Writer插件,纳入到整个同步框架中。

Reader:

Reader 为数据采集模块,负责采集数据源的数据,将数据发送给Framework。

Writer:

Writer为数据写入模块,负责不断向Framework取数据,并将数据写入到目的端。

Framework:

Framework用于连接reader和writer,作为两者的数据传输通道,并处理缓冲,流控,并发,数据转换等核心技术问题。

2.3 DataX3.0插件体系

经过几年积累,DataX目前已经有了比较全面的插件体系,主流的RDBMS数据库、NOSQL、大数据计算系统都已经接入。DataX目前支持数据如下:

DataX Framework提供了简单的接口与插件交互,提供简单的插件接入机制,只需要任意加上一种插件,就能无缝对接其他数据源。

详情请看:DataX数据源指南

 2.4 DataX3.0核心架构

DataX 3.0 开源版本支持单机多线程模式完成同步作业运行,本小节按一个DataX作业生命周期的时序图,从整体架构设计非常简要说明DataX各个模块相互关系。

 核心模块介绍:

  1. DataX完成单个数据同步的作业,我们称之为Job,DataX接受到一个Job之后,将启动一个进程来完成整个作业同步过程。DataX Job模块是单个作业的中枢管理节点,承担了数据清理、子任务切分(将单一作业计算转化为多个子Task)、TaskGroup管理等功能。

  2. DataXJob启动后,会根据不同的源端切分策略,将Job切分成多个小的Task(子任务),以便于并发执行。Task便是DataX作业的最小单元,每一个Task都会负责一部分数据的同步工作。

  3. 切分多个Task之后,DataX Job会调用Scheduler模块,根据配置的并发数据量,将拆分成的Task重新组合,组装成TaskGroup(任务组)。每一个TaskGroup负责以一定的并发运行完毕分配好的所有Task,默认单个任务组的并发数量为5。

  4. 每一个Task都由TaskGroup负责启动,Task启动后,会固定启动Reader—>Channel—>Writer的线程来完成任务同步工作。

  5. DataX作业运行起来之后, Job监控并等待多个TaskGroup模块任务完成,等待所有TaskGroup任务完成后Job成功退出。否则,异常退出,进程退出值非0

DataX调度流程:

举例来说,用户提交了一个DataX作业,并且配置了20个并发,目的是将一个100张分表的mysql数据同步到odps里面。 DataX的调度决策思路是:

  1. DataXJob根据分库分表切分成了100个Task。

  2. 根据20个并发,DataX计算共需要分配4个TaskGroup。

  3. 4个TaskGroup平分切分好的100个Task,每一个TaskGroup负责以5个并发共计运行25个Task。

2.5 六大核心优势

可靠的数据质量监控

完美解决数据传输个别类型失真问题

DataX旧版对于部分数据类型(比如时间戳)传输一直存在毫秒阶段等数据失真情况,新版本DataX3.0已经做到支持所有的强数据类型,每一种插件都有自己的数据类型转换策略,让数据可以完整无损的传输到目的端。

提供作业全链路的流量、数据量运行时监控

DataX3.0运行过程中可以将作业本身状态、数据流量、数据速度、执行进度等信息进行全面的展示,让用户可以实时了解作业状态。并可在作业执行过程中智能判断源端和目的端的速度对比情况,给予用户更多性能排查信息。

提供脏数据探测

在大量数据的传输过程中,必定会由于各种原因导致很多数据传输报错(比如类型转换错误),这种数据DataX认为就是脏数据。DataX目前可以实现脏数据精确过滤、识别、采集、展示,为用户提供多种的脏数据处理模式,让用户准确把控数据质量大关!

丰富的数据转换功能

DataX作为一个服务于大数据的ETL工具,除了提供数据快照搬迁功能之外,还提供了丰富数据转换的功能,让数据在传输过程中可以轻松完成数据脱敏,补全,过滤等数据转换功能,另外还提供了自动groovy函数,让用户自定义转换函数。详情请看DataX3的transformer详细介绍。  

精准的速度控制

还在为同步过程对在线存储压力影响而担心吗?新版本DataX3.0提供了包括通道(并发)、记录流、字节流三种流控模式,可以随意控制你的作业速度,让你的作业在库可以承受的范围内达到最佳的同步速度。

"speed": {
   "channel": 5,
   "byte": 1048576,
   "record": 10000
}

强劲的同步性能

DataX3.0每一种读插件都有一种或多种切分策略,都能将作业合理切分成多个Task并行执行,单机多线程执行模型可以让DataX速度随并发成线性增长。在源端和目的端性能都足够的情况下,单个作业一定可以打满网卡。另外,DataX团队对所有的已经接入的插件都做了极致的性能优化,并且做了完整的性能测试。性能测试相关详情可以参照每单个数据源的详细介绍:DataX数据源指南

健壮的容错机制

DataX作业是极易受外部因素的干扰,网络闪断、数据源不稳定等因素很容易让同步到一半的作业报错停止。因此稳定性是DataX的基本要求,在DataX 3.0的设计中,重点完善了框架和插件的稳定性。目前DataX3.0可以做到线程级别、进程级别(暂时未开放)、作业级别多层次局部/全局的重试,保证用户的作业稳定运行。

线程内部重试

DataX的核心插件都经过团队的全盘review,不同的网络交互方式都有不同的重试策略。

线程级别重试

目前DataX已经可以实现TaskFailover,针对于中间失败的Task,DataX框架可以做到整个Task级别的重新调度。

极简的使用体验

易用

下载即可用,支持linux和windows,只需要短短几步骤就可以完成数据的传输。请点击:Quick Start

详细

DataX在运行日志中打印了大量信息,其中包括传输速度,Reader、Writer性能,进程CPU,JVM和GC情况等等。

传输过程中打印传输速度、进度等

传输过程中会打印进程相关的CPU、JVM等

 

 在任务结束之后,打印总体运行情况

三、DataX的快速入门

3.1 环境需求

3.2 安装方式

方法1 直接下载DataX工具包

DataX下载地址:http://datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.gz

下载后解压至本地某个目录,进入bin目录,即可运行同步作业:

$ cd  {YOUR_DATAX_HOME}/bin
$ python datax.py {YOUR_JOB.json}

 自检脚本:

$ python {YOUR_DATAX_HOME}/bin/datax.py {YOUR_DATAX_HOME}/job/job.json

如果报错

经DataX智能分析,该任务最可能的错误原因是:
com.alibaba.datax.common.exception.DataXException: Code:[Common-00], Describe:[您提供的配置文件存在错误信息,请检查您的作业配置 .] - 配置信息错误,您提供的配置文件[/usr/local/datax/plugin/reader/._drdsreader/plugin.json]不存在. 请检查您的配置文件.
        at com.alibaba.datax.common.exception.DataXException.asDataXException(DataXException.java:26)
        at com.alibaba.datax.common.util.Configuration.from(Configuration.java:95)
        at com.alibaba.datax.core.util.ConfigParser.parseOnePluginConfig(ConfigParser.java:153)
        at com.alibaba.datax.core.util.ConfigParser.parsePluginConfig(ConfigParser.java:125)
        at com.alibaba.datax.core.util.ConfigParser.parse(ConfigParser.java:63)
        at com.alibaba.datax.core.Engine.entry(Engine.java:137)
        at com.alibaba.datax.core.Engine.main(Engine.java:204)

要运行以下指令

$ rm -rf {YOUR_DATAX_HOME}/plugin/*/._*

方法2 下载DataX源码,自己编译(不推荐)

DataX源码 : GitHub - alibaba/DataX: DataX是阿里云DataWorks数据集成的开源版本。

(1)、下载DataX源码:

$ git clone git@github.com:alibaba/DataX.git

(2)、通过maven打包:

$ cd  {DataX_source_code_home}
$ mvn -U clean package assembly:assembly -Dmaven.test.skip=true

打包成功,日志显示如下:

[INFO] BUILD SUCCESS
[INFO] -----------------------------------------------------------------
[INFO] Total time: 08:12 min
[INFO] Finished at: 2015-12-13T16:26:48+08:00
[INFO] Final Memory: 133M/960M
[INFO] -----------------------------------------------------------------

打包成功后的DataX包位于 {DataX_source_code_home}/target/datax/datax/ ,结构如下:

$ cd  {DataX_source_code_home}
$ ls ./target/datax/datax/
bin		conf		job		lib		log		log_perf	plugin		script		tmp

然后 拷贝到你喜欢的目录下,像方法1一样,去使用

3.3 查看常用的Reader和Writer插件样本

第一种方式

切换到相应的plugin/reader/或者是plugin/reader/下的插件目录下查看样本

[root@xxx01 streamreader]# pwd
/usr/local/datax/plugin/reader/streamreader
[root@xxx01 streamreader]# cat plugin_job_template.json

{
    "name": "streamreader",
    "parameter": {
        "sliceRecordCount": "",
        "column": []
    }
}

[root@xxx01 streamwriter]# pwd
/usr/local/datax/plugin/writer/streamwriter
[root@xxx01 streamwriter]# cat plugin_job_template.json
{
    "name": "streamwriter",
    "parameter": {
        "encoding": "",
        "print": true
    }
}

第二种方式:查看datax的github上的对应的文档

第三种方式:使用命令参数-r和-w查看读写插件

[root@xxx01 streamwriter]#  python {YOUR_DATAX_HOME}/bin/datax.py -r streamreader -w streamwriter

四、案例演示

4.1 Stream->Stream

获取样本并修改:

$  python /usr/local/datax/bin/datax.py -r streamreader -w streamwriter

修改如下: 目的是打印10行 hello,世界

$ vim /usr/local/datax/job/stream2Stream.json
{
   "job": {
      "content": [
         {
            "reader": {
               "name": "streamreader",
               "parameter": {
                  "column": [
                     {
                        type:"long",
                        value:"1024"
                     },{
                        type:"string",
                        value:"hello,世界"
                     }
                  ],
                  "sliceRecordCount": "10"
               }
            },
            "writer": {
               "name": "streamwriter",
               "parameter": {
                  "encoding": "utf-8",
                  "print": true
               }
            }
         }
      ],
      "setting": {
         "speed": {
            "channel": "2"
         }
      }
   }
}

并执行job

$ python /usr/local/datax/bin/datax.py /usr/local/datax/job/stream2Stream.json

4.2 mysql -> hdfs

目的:将mysql里的emp表导入到hdfs上的/datax/mysql2hdfs/

获取样本:

$  python /usr/local/datax/bin/datax.py -r mysqlreader -w hdfswriter

修改如下

$ vim /usr/local/datax/job/mysql2Hdfs.json
{
    "job": {
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "column": [
                           "empno",
                           "ename",
                           "job",
                           "mgr",
                           "hiredate",
                           "deptno"
                        ],
                        "connection": [
                            {
                                "jdbcUrl": ["jdbc:mysql://xxx03:3306/sz2103"],
                                "table": ["emp"]
                            }
                        ],
                        "password": "@Mmforu45",
                        "username": "root",
                        "where": "deptno = 10 or deptno = 20"
                    }
                },
                "writer": {
                    "name": "hdfswriter",
                    "parameter": {
                        "column": [
                           {
                              type:"int",
                              name:"empno"
                           },{
                              type:"string",
                              name:"ename"
                           },{
                              type:"string",
                              name:"job"
                           },{
                              type:"int",
                              name:"mgr"
                           },{
                              name:"hiredate",
                              type:"date"
                           },{
                              name:"dept",
                              type:"int"
                           }
                        ],
                        "defaultFS": "hdfs://xxx01:8020",
                        "fieldDelimiter": "\t",
                        "fileName": "mysqlToHdfs",
                        "fileType": "orc",
                        "path": "/datax/mysql2hdfs",
                        "writeMode": "append"
                    }
                }
            }
        ],
        "setting": {
            "speed": {
                "channel": "2"
            }
        }
    }
}

运行测试

$ python /usr/local/datax/bin/datax.py /usr/local/datax/job/mysql2Hdfs.json

4.3 mysql->hive

说明:用的其实就是hdfs的写插件

$ vim /usr/local/datax/job/mysql2Hive.json
由于没有在hive中创建表,因此要提前创建相应的目录
hdfs dfs -mkdir /user/hive/warehouse/sz2103.db/orc_emp
{
    "job": {
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "column": [
                           "empno",
                           "ename",
                           "job",
                           "mgr",
                           "hiredate",
                           "sal",
                           "comm",
                           "deptno"
                        ],
                        "connection": [
                            {
                                "jdbcUrl": ["jdbc:mysql://xxx03:3306/sz2103"],
                                "table": ["emp"]
                            }
                        ],
                        "password": "@Mmforu45",
                        "username": "root"
                    }
                },
                "writer": {
                    "name": "hdfswriter",
                    "parameter": {
                        "column": [
                           {
                              type:"int",
                              name:"empno"
                           },{
                              type:"string",
                              name:"ename"
                           },{
                              type:"string",
                              name:"job"
                           },{
                              type:"int",
                              name:"mgr"
                           },{
                              name:"hiredate",
                              type:"date"
                           },{
                              type:"double",
                              name:"salary"
                           },{
                              type:"double",
                              name:"comm"
                           },{
                              name:"deptno",
                              type:"int"
                           }
                        ],
                        "defaultFS": "hdfs://xxx01:8020",
                        "fieldDelimiter": "\t",
                        "fileName": "mysqlToHdfs",
                        "fileType": "orc",
                        "path": "/user/hive/warehouse/sz2103.db/orc_emp",
                        "writeMode": "append"
                    }
                }
            }
        ],
        "setting": {
            "speed": {
                "channel": "2"
            }
        }
    }
}

运行测试:

$ python /usr/local/datax/bin/datax.py /usr/local/datax/job/mysql2Hive.json

由于之前没有创建hive表,所以最后要把hive参考配置的字段来设计hive表并创建

create table if not exists orc_emp(
empno int,
ename string,
job string,
mgr int,
hiredate date,
salary double,
comm double,
deptno int
)
row format delimited 
fields terminated by "\t" 
stored as orc;

4.4 hdfs -> mysql

注意:mysql要提前创建表

获取样本:

$  python /usr/local/datax/bin/datax.py -r hdfsreader -w mysqlwriter

修改如下

$ vim /usr/local/datax/job/hdfs2mysql.json

小贴士:

datax读取的hdfs上的文件:  文件里的数据都应该被当成字符串读取,然后进入到datax里转成datax自己的类型
{
    "job": {
        "content": [
            {
                "reader": {
                    "name": "hdfsreader",
                    "parameter": {
                        "column": [
                           {
                              index:0,
                              type:"long"
                           },{
                              index:1,
                              type:"string"
                           },{
                              index:2,
                              type:"string"
                           },{
                              index:3,
                              type:"long"
                           },{
                              index:4,
                              type:"date"
                           },{
                              index:5,
                              type:"long"
                           }
                        ],
                        "defaultFS": "hdfs://xxx01",
                        "encoding": "UTF-8",
                        "fieldDelimiter": "\t",
                        "fileType": "orc",
                        "path": "/datax/mysql2hdfs/*"
                    }
                },
                "writer": {
                    "name": "mysqlwriter",
                    "parameter": {
                        "column": [
                           "empno",
                           "ename",
                           "job",
                           "mgr",
                           "hiredate",
                           "deptno"
                        ],
                        "connection": [
                            {
                                "jdbcUrl": "jdbc:mysql://xxx03:3306/sz2103",
                                "table": ["hdfs2mysql"]
                            }
                        ],
                        "password": "@Mmforu45",
                        "username": "root",
                        "writeMode": "insert"
                    }
                }
            }
        ],
        "setting": {
            "speed": {
                "channel": "2"
            }
        }
    }
}

$ python /usr/local/datax/bin/datax.py /usr/local/datax/job/hdfs2mysql.json

4.5 hive->mysql

提前在mysql里创建表

修改如下

$ vim /usr/local/datax/job/hive2mysql.json
{
    "job": {
        "content": [
            {
                "reader": {
                    "name": "hdfsreader",
                    "parameter": {
                        "column": [
                           {
                              index:0,
                              type:"long"
                           },{
                              index:1,
                              type:"string"
                           },{
                              index:2,
                              type:"string"
                           },{
                              index:3,
                              type:"long"
                           },{
                              index:4,
                              type:"date"
                           },{
                              index:5,
                              type:"double"
                           },{
                              index:6,
                              type:"double"
                           },{
                              index:7,
                              type:"long"
                           }
                        ],
                        "defaultFS": "hdfs://xxx01",
                        "encoding": "UTF-8",
                        "fieldDelimiter": "\t",
                        "fileType": "orc",
                        "path": "/user/hive/warehouse/sz2103.db/orc_emp/*"
                    }
                },
                "writer": {
                    "name": "mysqlwriter",
                    "parameter": {
                        "column": ["*"],
                        "connection": [
                            {
                                "jdbcUrl": "jdbc:mysql://xxx03:3306/sz2103",
                                "table": ["hive2mysql"]
                            }
                        ],
                        "password": "@Mmforu45",
                        "username": "root",
                        "writeMode": "insert"
                    }
                }
            }
        ],
        "setting": {
            "speed": {
                "channel": "2"
            }
        }
    }
}

$ python /usr/local/datax/bin/datax.py /usr/local/datax/job/hive2mysql.json

4.6 增量导入

使用table和where两个参数或者querySql参数进行增量导入

$ vim /usr/local/datax/job/mysql2hdfs_increment.json
{
    "job": {
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "column": [
                           "empno",
                           "ename",
                           "job",
                           "mgr",
                           "hiredate",
                           "deptno"
                        ],
                        "connection": [
                            {
                                "jdbcUrl": ["jdbc:mysql://xxx03:3306/sz2103"],
                                "querySql":["select empno,ename,job,mgr,hiredate,deptno from emp where deptno > '${deptno}'"]
                            }
                        ],
                        "password": "@Mmforu45",
                        "username": "root"
                    }
                },
                "writer": {
                    "name": "hdfswriter",
                    "parameter": {
                        "column": [
                           {
                              type:"int",
                              name:"empno"
                           },{
                              type:"string",
                              name:"ename"
                           },{
                              type:"string",
                              name:"job"
                           },{
                              type:"int",
                              name:"mgr"
                           },{
                              name:"hiredate",
                              type:"date"
                           },{
                              name:"dept",
                              type:"int"
                           }
                        ],
                        "defaultFS": "hdfs://xxx01:8020",
                        "fieldDelimiter": "\t",
                        "fileName": "mysqlToHdfs",
                        "fileType": "text",
                        "path": "/datax/mysql2hdfs",
                        "writeMode": "append",
                    }
                }
            }
        ],
        "setting": {
            "speed": {
                "channel": "2"
            }
        }
    }
}

给形参赋值

赋值格式: -p "-DpropertyName=propertyValue -D........"
$ python /usr/local/datax/bin/datax.py /usr/local/datax/job/mysql2hdfs_increment.json -p "-Dstart_value=20 -D"

五、DataX调优方案

1,网络本身的带宽等硬件因素造成的影响; 2,DataX本身的参数; 3,从源端到任务机; 4,从任务机到目的端; 即当觉得DataX传输速度慢时,需要从上述四个方面着手开始排查。

此部分主要需要了解网络本身的情况,即从源端到目的端的带宽是多少(实际带宽计算公式),平时使用量和繁忙程度的情况,从而分析是否是本部分造成的速度缓慢。以下提供几个思路。

1,可使用从源端到目的端scp,python http,nethogs等观察实际网络及网卡速度; 2,结合监控观察任务运行时间段时,网络整体的繁忙情况,来判断是否应将任务避开网络高峰运行; 3,观察任务机的负载情况,尤其是网络和磁盘IO,观察其是否成为瓶颈,影响了速度;

全局

{
   "core":{
        "transport":{
            "channel":{
                "speed":{
                    "channel": 2, ## 此处为数据导入的并发度,建议根据服务器硬件进行调优
                    "record":-1, ##此处解除对读取行数的限制
                    "byte":-1, ##此处解除对字节的限制
                    "batchSize":2048 ##每次读取batch的大小
                }
            }
        }
    },
    "job":{
            ...
        }
    }

局部

"setting": {
            "speed": {
                "channel": 2,
                "record":-1,
                "byte":-1,
                "batchSize":2048
            }
        }
    }
}

# channel增大,为防止OOM,需要修改datax工具的datax.py文件。
# 如下所示,可根据任务机的实际配置,提升-Xms与-Xmx,来防止OOM。
# tunnel并不是越大越好,过分大反而会影响宿主机的性能。
DEFAULT_JVM = "-Xms1g -Xmx1g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=%s/log" % (DATAX_HOME)

Jvm 调优

python datax.py  --jvm="-Xms3G -Xmx3G" ../job/test.json

此处根据服务器配置进行调优,切记不可太大!否则直接Exception 以上为调优,应该是可以针对每个json文件都可以进行调优。

官方调优:DataX使用指南——ODPS to ODPS-阿里云开发者社区

(>_<距离挥手告别2021还有三天,回首望月,今年可以说成长了很多,有失落也有惊喜,希望能在2021的最后几天做出点成绩来!祝大家在年末都能得偿所愿~~~)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值