10-datax--基础

一、DataX基础

1、了解

java 解决的是高并发问题,大数据解决的是海量数据存储与分析问题。

可以理解为国内版的Sqoop。
但是比Sqoop要快,Sqoop底层是MR(Map任务),基于磁盘的,DataX基于内存的,所以速度比较快。

DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL、SQL Server、Oracle、PostgreSQL、HDFS、Hive、HBase、OTS、ODPS 等各种异构数据源之间高效的数据同步功能。

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

关系型数据库的数据都是结构化的,排列非常整齐
非关系型数据库都是非结构化的,非常的错乱。(异构)

image.png

2、下载地址 

此前已经开源DataX1.0版本,此次介绍为阿里云开源全新版本DataX3.0,有了更多更强大的功能和更好的使用体验。Github主页地址:https://github.com/alibaba/DataX

DataX是阿里云DataWorks数据集成的开源版本。

假如github访问速度比较慢,或者访问不上,科学上网。

也可以使用FastGitHub软件。

再次访问:

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

3、DataX3.0 框架设计

类似于之前的Flume:

source  -->  ReadPlugin
channel --> Channel
sink   --> WritePlugin

4、支持的数据源有哪些(几乎所有)

5、核心架构

一个Job要想执行,可能会拆分成多个Task任务,这些任务又会分为很多个组,每一个组里面,又根据channel的数量,进行汇总,并行执行,默认一个TaskGroup 有 5个channel

计算题:
假如一个Job,被拆分为100个任务,20 个组,每个组里面并行执行5个任务。

job  100个任务
TaskGroup 假如需要20个并发量
每一个TaskGroup 默认是5个任务
用户提交了一个DataX作业,并且配置了20个并发,目的是将一个100张分表的mysql数据同步到HDFS里面。 DataX的调度决策思路是:
1.  DataXJob根据分库分表切分成了100个Task。
2.  根据20个并发,DataX计算共需要分配4个TaskGroup。
3.  4个TaskGroup平分切分好的100个Task,每一个TaskGroup负责以5个并发共计运行25个Task

image.png

6、安装 

1、上传  /opt/modules
2、解压   tar -zxvf datax.tar.gz  -C /opt/installs
3、修改/etc/profile
   配置环境变量:
   export DATAX_HOME=/opt/installs/datax
   export PATH=$PATH:$DATAX_HOME/bin
   
   source /etc/profile

测试一下:

Play一下自带的案例:

编辑这个案例:job.json文件

运行一下:

datax.py job.json

假如你运行报错如下:

报错:

配置信息错误,您提供的配置文件[/opt/installs/datax/plugin/reader/._drdsreader/plugin.json]不存在. 请检查您的配置文件

 解决方案如下:

rm -rf /opt/installs/datax/plugin/*/._*

说明运行该脚本的位置不对,找不到对应的json文件。

因为以后要链接mysql数据库,mysql数据库的驱动包少不了:

cp /opt/installs/sqoop/lib/mysql-connector-java-8.0.26.jar /opt/installs/datax/lib/

7、实战

1) MySQLReader 案例

在job 文件夹 创建一个文件 mysql2stream.json ,代码如下

{
  "job": {
    "setting": {
      "speed": {
        "channel":1
      }
    },
    "content": [
      {
        "reader": {
          "name": "mysqlreader",
          "parameter": {
            "username": "root",
            "password": "123456",
            "connection": [
              {
                "querySql": [
                  "select * from emp where empno < 7788;"
                ],
                "jdbcUrl": [
                  "jdbc:mysql://bigdata01:3306/sqoop"
                ]
              }
            ]
          }
        },
        "writer": {
          "name": "streamwriter",
          "parameter": {
            "print": true,
            "encoding": "UTF-8"
          }
        }
      }
    ]
  }
}

读取mysql的数据,将数据展示在控制台上。此时的stream其实就是控制台

{
  "job": {
    "setting": {
      "speed": {
        "channel": 3
      },
      "errorLimit": {
        "record": 0,
        "percentage": 0.02
      }
    },
    "content": [
      {
        "reader": {
          "name": "mysqlreader",
          "parameter": {
            "username": "root",
            "password": "123456",
            "column": [
              "empno",
              "ename"
            ],
            "splitPk": "empno",
            "connection": [
              {
                "table": [
                  "emp"
                ],
                "jdbcUrl": [
                  "jdbc:mysql://bigdata01:3306/sqoop"
                ]
              }
            ]
          }
        },
        "writer": {
          "name": "streamwriter",
          "parameter": {
            "print":true
          }
        }
      }
    ]
  }
}

运行:

datax.py mysql2stream.json

2) 含有sql语句的mysqlReader案例

{
    "job": {
        "setting": {
            "speed": {
                "channel": 1
            }
        },
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "username": "root",
                        "password": "123456",
                        "connection": [
                            {
                                "querySql": ["select * from emp where comm is not null;"],
                                "jdbcUrl": ["jdbc:mysql://bigdata01:3306/sqoop"]
                            }
                        ]
                    }
                },
                "writer": {
                    "name": "streamwriter",
                    "parameter": {
                        "print": true,
                        "encoding": "UTF-8"
                    }
                }
            }
        ]
    }
}

特殊说明:

如果你编写的json文件中需要用到字段类型,必须指定DataX内部类型,不要使用Mysql类型和java类型

3) MySQLWriter 展示

{
    "job": {
        "setting": {
            "speed": {
                "channel": 1
            }
        },
        "content": [
            {
                "reader": {
                    "name": "streamreader",
                    "parameter": {
                        "column": [
                            {"value": "9870", "type": "long" },
                            {"value": "SHAWN", "type": "string"},
                            {"value": "BOSS", "type": "string"},
                            {"value": "1999-01-01", "type": "string"},
                            {"value": "99999", "type": "long"}
                        ],
                        "sliceRecordCount": 10
                    }
                },
                "writer": {
                    "name": "mysqlwriter",
                    "parameter": {
                        "writeMode": "insert",
                        "username": "root",
                        "password": "123456",
                        "column": ["empno", "ename", "job", "hiredate", "sal"],
                        "connection": [
                            {
                                "jdbcUrl": "jdbc:mysql://bigdata01:3306/sqoop",
                                "table": ["emp"]
                            }
                        ]
                    }
                }
            }
        ]
    }
}

由于emp表中empno是主键,所以10条数据,只插入了一条。

mysql Writer 的另一个案例:

{
    "job": {
        "setting": {
            "speed": {
                "channel": 1
            }
        },
        "content": [
            {
                "reader": {
                    "name": "streamreader",
                    "parameter": {
                        "column": [
                            {"value": "9870", "type": "long" },
                            {"value": "ZhangSan", "type": "string"},
                            {"value": "BOSS", "type": "string"},
                            {"value": "1999-01-01", "type": "string"},
                            {"value": "99999", "type": "long"}
                        ],
                        "sliceRecordCount": 10
                    }
                },
                "writer": {
                    "name": "mysqlwriter",
                    "parameter": {
                        "writeMode": "replace",
                        "username": "root",
                        "password": "123456",
                        "column": ["empno", "ename", "job", "hiredate", "sal"],
                        "preSql": ["delete from emp"],
                        "connection": [
                            {
                                "jdbcUrl": "jdbc:mysql://bigdata01:3306/sqoop",
                                "table": ["emp"]
                            }
                        ]
                    }
                }
            }
        ]
    }
}
insert into   插入   不判断,直接插入
replace into  先查看这个主键是否有数据,如果有直接删除并插入,如果没有,直接插入。

4) HDFSReader 案例展示

{
    "job": {
        "setting": {
            "speed": {
                "channel": 3
            }
        },
        "content": [
            {
                "reader": {
                    "name": "hdfsreader",
                    "parameter": {
                        "path": "/home/a.txt",
                        "defaultFS": "hdfs://bigdata01:9820",
                        "column": [ "*" ],
                        "fileType": "text"
                    }
                },
                "writer": {
                    "name": "streamwriter",
                    "parameter": {
                        "print": true
                    }
                }
            }
        ]
    }
}

5) HDFS只读取部分列值

{
    "job": {
        "setting": {
            "speed": {
                "channel": 3
            }
        },
        "content": [
            {
                "reader": {
                    "name": "hdfsreader",
                    "parameter": {
                        "path": "/home/1.txt",
                        "defaultFS": "hdfs://bigdata01:9820",
                        "column": [
                            
                            {"index": 1, "type": "long"},
                            {"index": 0, "type": "long"},
                            {"value": "老闫真帅", "type": "string"}
                        ],
                        "fileType": "text",
                        "encoding": "UTF-8",
                        "filedDelimiter": ","
                    }
                },
                "writer": {
                    "name": "streamwriter",
                    "parameter": {
                        "print": true
                    }
                }
            }
        ]
    }
}

6) 将数据导入到hdfs上,即 hdfsWriter 案例

{
    "job": {
        "setting": {
            "speed": {
                "channel": 3
            }
        },
        "content": [
            {
                "reader": {
                    "name": "streamreader",
                    "parameter": {
                        "column": [
                            {"value": "9870", "type": "long" },
                            {"value": "SHAWN", "type": "string"},
                            {"value": "BOSS", "type": "string"},
                            {"value": "1999-01-01", "type": "string"},
                            {"value": "99999", "type": "long"}
                        ],
                        "sliceRecordCount": 10
                    }
                },
                "writer": {
                    "name": "hdfswriter",
                    "parameter": {
                        "defaultFS": "hdfs://bigdata01:9820",
                        "path": "/datax/emp",
                        "fileName": "emp",
                        "column": [
                            {"name": "empno", "type": "string"},
                            {"name": "ename", "type": "string"},
                            {"name": "job", "type": "string"},
                            {"name": "hiredate", "type": "string"},
                            {"name": "sal", "type": "double"}
                        ],
                        "fileType": "text",
                        "writeMode": "append",
	                      "fieldDelimiter": "\t"
                    }
                }
            }
        ]
    }
}

说明 hdfs上的路径必须提前创建好

hdfs dfs -mkdir -p /datax/emp

7) 将mysql的数据导入到hive中(重要)

第一步:创建mysql的表 base_area

需要使用base_area.sql

第二步:在hive中创建一个ods_01_base_area

create external table if not exists ods_01_base_area (
  id int COMMENT 'id标识',
  area_code string COMMENT '省份编码',
  province_name string COMMENT '省份名称',
  iso string COMMENT 'ISO编码'
)row format delimited fields terminated by ','
stored as TextFile
location '/data/nshop/ods/ods_01_base_area/';

从mysql导入到hive中(其实就是导入到hdfs)

编写对应的Job的json文件:

read 方 是mysqlreader

write 方 是 hive (没有找到,找到了hdfswriter)

在 job文件夹,创建一个 mysql2hive01.json

{
    "job": {
        "setting": {
            "speed": {
                 "channel": 3
            },
            "errorLimit": {
                "record": 0,
                "percentage": 0.02
            }
        },
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "writeMode": "insert",
                        "username": "root",
                        "password": "123456",
                        "column": [
                            "id",
                            "area_code",
                            "province_name",
                            "iso"
                        ],
                        "splitPk": "id",
                        "connection": [
                            {
                                "table": [
                                    "base_area"
                                ],
                                "jdbcUrl": [
     "jdbc:mysql://bigdata01:3306/sqoop"
                                ]
                            }
                        ]
                    }
                },
               "writer": {
                    "name": "hdfswriter",
                    "parameter": {
                        "defaultFS": "hdfs://bigdata01:9820",
                        "fileType": "text",
                        "path": "/data/nshop/ods/ods_01_base_area/",
                        "fileName": "base_area_txt",
                        "column": [
                            {
                                "name": "id",
                                "type": "int"
                            },
                            {
                                "name": "area_code",
                                "type": "string"
                            },
                            {
                                "name": "province_name",
                                "type": "string"
                            },
                            {
                                "name": "iso",
                                "type": "string"
                            }
                        ],
                        "writeMode": "append",
                        "fieldDelimiter": ","
                    }
                }
            }
        ]
    }
}

8、datax如何做增量导入

sqoop增量导入有两种方案:

1、使用where语句 2、使用last-value 和 job任务一起使用,让job记住last-value

datax只有一种方案:使用where语句

举例:

image.png

如果json中有变量,需要传递值,在运行的时候,使用-D  传递即可

datax.py job/append.json -p "-Dstart_time=2021-01-01 -Dend_time=2021-01-03"

 第二种还是使用where条件,只是这个时候的where条件是在SQL语句中

9、关于datax的调优

在datax中有两种配置文件,一种全局的,一种局部的。

全局的是 conf/core.json

也可以通过 record 和 byte 进行限速,这个值是每秒的条数和字节大小。

这个地方可以调整channel的各项参数,并发度默认是5个。

局部的配置文件,就是自己写的 xxxx.json

参数调优:

1、调整channel的数量,扩大并发度
2、调整jvm堆的大小,调整方案可以使用局部调整
    python datax.py  --jvm="-Xms3G -Xmx3G" ../job/test.json
   一般这个任务比较大,报OOM异常了,或者GC次数特别的情况下,就可以指定堆大小。
   指定的时候为什么初识容量大小和最大容量是一样的呢?
   因为从初识容量到最大容量,需要不断的尝试,这个也比较耗时,所以一步到位即可。

关于并行度的说明

DataX的限速与调优 - 墨天轮

 

二、DataX高级部分

1、数据从hive导出到mysql

重要:一般都是将hive中分析的结果,存入到hive的一个表中,web端想展示,必须将hive中的数据导出到mysql或者其他关系型数据库中。

数据准备:

查看hive中是否有数据:

在mysql中创建一个表,用于存放数据。

目标:从par3中导出数据到mysql的user表。

在咱们的datax中没hiveReader,但是有hdfsreader,所以本质上就是hdfs导出到mysql

{
  "job": {
    "setting": {
      "speed": {
        "channel": 3
      }
    },
    "content": [
      {
        "reader": {
          "name": "hdfsreader",
          "parameter": {
            "path": "/user/hive/warehouse/yhdb.db/par3/*",
            "defaultFS": "hdfs://bigdata01:9820",
            "column": [
              {
                "index": 0,
                "type": "long"
              },
              {
                "index": 1,
                "type": "long"
              }
            ],
            "fileType": "text",
            "encoding": "UTF-8",
            "fieldDelimiter": ","
          }
        },
        "writer": {
          "name": "mysqlwriter",
          "parameter": {
            "writeMode": "insert",
            "username": "root",
            "password": "123456",
            "column": [
              "id",
              "age"
            ],
            "connection": [
              {
                "jdbcUrl": "jdbc:mysql://bigdata01:3306/sqoop",
                "table": [
                  "user"
                ]
              }
            ]
          }
        }
      }
    ]
  }
}

结果展示:

2、DataX Web -- 图形化的DataX界面而已

1)介绍

github地址:https://github.com/WeiYe-Jing/datax-web

2) 安装

1、上传
2、解压
tar -zxvf datax-web-2.1.2.tar.gz -C /opt/installs/
3、安装
cd /opt/installs/datax-web-2.1.2/bin
执行安装程序
./install.sh

3)修改配置文件

vi /opt/installs/datax-web-2.1.2/modules/datax-executor/bin/env.properties

修改此处:
PYTHON_PATH=/opt/installs/datax/bin/datax.py

4)启动和关闭

bin路径下,有一个 start-all.sh  启动
stop-all.sh 关闭
不要配置环境变量

/opt/installs/datax-web-2.1.2/bin
运行的时候  ./start-all.sh

5) 浏览

在上一步启动dataxweb之后,通过浏览器可以进行dataxweb的访问,具体地址如下:
http://192.168.52.10:9527/index.html
进入网页之后,要求输入登录的用户名与密码,使用默认的即可:
用户名:admin
密码:123456

6)查看jps

7) 使用

第一步:创建一个项目

第二步:添加数据源

首先添加mysql数据源:

添加hive的数据源:

启动hive的远程连接:

hiveserver2

通过beeline测试连接:

[root@hadoop10 ~]# beeline
Beeline version 3.1.2 by Apache Hive
beeline> !connect jdbc:hive2://hadoop10:10000
Connecting to jdbc:hive2://hadoop10:10000
Enter username for jdbc:hive2://hadoop10:10000: 
Enter password for jdbc:hive2://hadoop10:10000: 
Connected to: Apache Hive (version 3.1.2)
Driver: Hive JDBC (version 3.1.2)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://hadoop10:10000> show databases;
INFO  : Compiling command(queryId=root_20230625195657_077b4fad-4d99-4574-ba7e-4fbe524ae63a): show databases
INFO  : Concurrency mode is disabled, not creating a lock manager
INFO  : Semantic Analysis Completed (retrial = false)
INFO  : Returning Hive schema: Schema(fieldSchemas:[FieldSchema(name:database_name, type:string, comment:from deserializer)], properties:null)
INFO  : Completed compiling command(queryId=root_20230625195657_077b4fad-4d99-4574-ba7e-4fbe524ae63a); Time taken: 1.446 seconds
INFO  : Concurrency mode is disabled, not creating a lock manager
INFO  : Executing command(queryId=root_20230625195657_077b4fad-4d99-4574-ba7e-4fbe524ae63a): show databases
INFO  : Starting task [Stage-0:DDL] in serial mode
INFO  : Completed executing command(queryId=root_20230625195657_077b4fad-4d99-4574-ba7e-4fbe524ae63a); Time taken: 0.052 seconds
INFO  : OK
INFO  : Concurrency mode is disabled, not creating a lock manager
+----------------+
| database_name  |
+----------------+
| default        |
| test_hive      |
| workspaces     |
| yhdb           |
+----------------+
4 rows selected (2.199 seconds)

连接正常再进行配置:

添加datx模板

名词解释:
- 执行器:目前只有datax可选
- 路由策略:用于集群化部署后,任务的分配,默认随机即可。
- 阻塞处理:在调度出现积压时(同时启动大量的数据处理任务)使用的策略:
  - 单机串行:调度请求进入单机执行器后,调度请求进入FIFO队列并以串行方式运行;
  - 丢弃后续调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,本次请求将会被丢弃并标记为失败;
  - 覆盖之前调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,将会终止运行中的调度任务并清空队列,然后运行本地调度任务;
    `建议使用单机串行与丢弃后续调度`
- 任务类型:目前只有DataX选项可以选择
- Cron:调度定时执行器,通过该配置可以完成定时、定周期启动

 

编写任务(以hive数据导出到mysql为例)

配置hdfsreader

配置mysqlwriter:

配置字段映射:

查看json:

记得点击【下一步】,否则任务不创建。

查看任务并执行:

查看运行结果和日志:

编辑任务:

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YuPangZa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值