DataX实战应用

目录

前言

系统架构

关键实现

系统目前使用现状

DataX使用心得


前言

DataX是阿里开源数据同步工具,实现异构数据源的数据同步,Github地址:https://github.com/alibaba/DataX,企业存储离线数据到数仓,但是没办法对接业务,本次实践主要是运用DataX实现数据从数仓导入到MySQL,从而对接业务,另外,对数仓数据的流出进行管理。

一般从数仓数据导入到MySQL中,可以从hive查询存储到一个文件里面,如果是数据量比较大的情况下先将文件按一定行数切分为多个文件,然后遍历文件往MySQL中导入,这种方式虽然简单,缺点在于对于每一个导入需求,都需要写一个job,并且每次都会产生临时文件,mysql load会比较占用资源,之所以选择了DataX,因为它能实现hdfs导入MySQL,速度快,能实现增量全量,可以分表,能减少很多技术的实现成本。

系统架构

本次应用主要需实现一个Client和Server,依托于Hadoop集群,通过Schedule基础平台定时调度调用client实现数据的同步。Server是一个管理项目,后端使用Spring MVC工程,对接了元数据系统,直接从前端页面可以配置从Hive表导入到具体的MySQL表,client是一个jar包,通过HTTP和MQ和Server通信。

运行流程

1.Schedule通过java -jar client.jar启动client

2.client通过http接口调用到server,获取到本次要同步的一个job,通过job的信息生成一个json串,分配一个线程,client中通过python datax.py xxx.json调用DataX完成数据同步

3.client完成json文件的输出,输出到指定的文件夹下,文件名采用时间戳命名。

4. client中通过执行shell命令完成对DataX的调用

发布流程:

1.DataX部署,这里只使用到了mysqlwriter和hdfsreader组件,所以通过clone DataX源码,删除掉了其余不用的组件代码,手动编译进行部署,编译后大约占用200M空间,部署到hadoop集群的各个slave机器,正常情况下DataX只需要一次部署。

2.server发布,server通过jenkins发布为一个web工程,后端提供http接口,并监听MQ。

3.client发布,client通过jenkins发布到hadoop集群的slave机器。

关键实现

1.日志监控,schedule调起client任务一次对应的日志应该都要全部输出到schedule中,并且应该要捕捉到DataX的运行日志。关键代码:

//commond是运行DataX的命令:python datax/bin/datax.py xxx.json 
Process process = RUNTIME.exec(command);
try (BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
	String line;
	while ((line = input.readLine()) != null) {
		System.out.println(line);
	}
} catch (IOException e) {
	LOG.error("读取DataX中job运行日志异常", e);
}

2.作业告警,采用了Schedule调度系统的告警,DataX导入失败会触发调度系统的告警,然后通过电话和邮件对负责人进行通知。

3.Hive分区表,hive中对单个表进行分区存储,一般按照日期进行分区,在schedule调起client时可以传入一个日期参数,然后根据日期生成一个日期分区,在hdfsreader中的分区中带入即可:

 "path": "/user/hive/warehouse/order/20180831",
 "defaultFS": "hdfs://localhost:2181",

4.MySQL增量和全量,DataX很贴心,mysqlwriter可以选择导入的模式。

"writer":{
    "name": "mysqlwriter",
    "parameter": {
        "writeMode": "insert",  // 写入模式可以选择insert/replace/update
        "username": "root",
        "password": "root",
        "column": [
            "id",
            "name"
        ],
        "session": [
            "set session sql_mode='ANSI'"
        ],
        "preSql": [
            "delete from test" // 预执行SQL,可以选择一个delete语句
        ],
        "connection": [
            {
                "jdbcUrl": "jdbc:mysql://127.0.0.1:3306/datax?useUnicode=true&characterEncoding=gbk",
                "table": [
                    "test"
                ]
            }
        ]
    }
}

其中parameter中的writeMode可以选择insert,update,replace。并且有preSql选项,也就是在导入之前可以执行一些SQL,对我们全量数据和增量数据提供了有效的方案。

全量数据导入:通过preSql传入一条delete语句,然后writerMode选择insert执行导入(甚至如果有比较高的权限,可以直接用truncate语句,但是一般dba才有的这样权限),在delete的时候需要注意,如果数据量太大的情况下,一条delete就足以让dba找上门拉,所以添加索引就有必要拉,根据索引删除就会快一些。

增量数据导入:选择writeMode使用update,这里dataX是通过on duplicate key update语句来实现数据的增量实现,也就是说表里面有唯一键或者主键冲突时,覆盖原来的数据,这就很容易理解了,比如订单数据,订单号肯定是一个唯一键,如果导入一个已存在的订单,数据肯定会覆盖原来的数据。

5.为什么要用MQ,这里client在调用DataX执行完成之后,应该要通知到server,当前的任务执行完毕,server会更新当前任务的状态,对于简单检查任务的状态时,就不用去查看schedule中的日志了。

系统目前使用现状

1.稳定性强,系统上线2个月以来,有大约20个作业在运行,其中有5个小时运行的作业,从来没有出现过问题。

2.速度快,目前同步数据量最大的一个表大概是1.4亿的数据量,同步的时间在1100s左右,也就是18分钟到19分钟这样一个时间,每秒最高写入量达到14w+,平均每秒写入量大约在13w左右的速度,速度保持一个平均的趋势,下面是一个运行结果的截图

DataX使用心得

1.DataX是一个高可用的数据同步工具,稳定性强,速度快,上手快(不知道二次开发会不会困难,有机会可以试试,但是目前的功能已经能满足很大一部分需求)。

2.事务的支持不足,在github上看到的DataX支持的一个线程中的事务,在测试过程中没有体会到这种小事务能带来多大的收益,在有脏数据的情况下,如果当前线程的数据出现问题执行回滚,其实对于整体来说数据是不完整的,还是有一部分数据已经导入到MySQL 了,所以单个线程的事务其实对于数据量较大的数据来说收益不大,除非作业是通过一个线程来跑的。

但是,另一方面,如果在大量数据导入执行一个事务,对MySQL来说无疑是一个灾难,所以最好的办法是保证系统结构稳定。

这里其实有一个办法,如果是全量的数据,在job跑失败之后重新跑,能证数据的准确性,但是跑失败的那段时间数据是有缺失的;如果是增量数据导入,重新跑一下job也能保证数据没有问题。但是在那段小时间内还是有问题的。

确实是没有什么好的办法去支持完整的事务。

欢迎交流。

  • 6
    点赞
  • 16
    评论
  • 10
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页

打赏

我是蚁人

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者