阿里开源的异构数据源离线同步工具--DataX

282 阅读11分钟

DataX介绍:

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

DataX设计理念

DataX本身作为数据同步框架,将不同数据源的同步抽象为从源头数据源读取数据的Reader插件,以及向目标端写入数据的Writer插件,理论上DataX框架可以支持任意数据源类型的数据同步工作。同时DataX插件体系作为一套生态系统, 每接入一套新数据源该新加入的数据源即可实现和现有的数据源互通。

image.png

DataX插件体系

DataX目前已经有了比较全面的插件体系,主流的RDBMS数据库、NOSQL、大数据计算系统都已经接入,目前支持数据如下图,详情请点击:DataX数据源参考指南

配置文件

DataX使用json作为配置文件的格式。一个典型的DataX任务配置如下:

{
  "job": {
    "content": [
      {
        "reader": {
          "name": "odpsreader",
          "parameter": {
            "accessKey": "",
            "accessId": "",
            "column": [""],
            "isCompress": "",
            "odpsServer": "",
            "partition": [
              ""
            ],
            "project": "",
            "table": "",
            "tunnelServer": ""
          }
        },
        "writer": {
          "name": "oraclewriter",
          "parameter": {
            "username": "",
            "password": "",
            "column": ["*"],
            "connection": [
              {
                "jdbcUrl": "",
                "table": [
                  ""
                ]
              }
            ]
          }
        }
      }
    ]
  }
}

DataX 3.0六大核心优势

  • 可靠的数据质量监控

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

      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情况等等。

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

        datax_run_speed转存失败,建议直接上传图片文件

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

        datax_run_cpu

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

        datax_end_info

Datax 与 sqoop 对比

image.png

Datax 使用

全中文文档完全不用担心看不懂

1.下载:

可以根据gitub地址下载源码进行编译源码地址:github.com/alibaba/Dat…,也可以根据下载链接直接下载 datax.tar.gz datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.g…

2.环境要求:

-linux -JDK(1.8以上,推荐1.8) -Python(这里使用的是linux自带Python2.7.5) 默认情况下,Linux会自带安装Python,可以运行python --version 命令查看

image.png 将下载好的tar包解压到指定目录 这里已Xshell5,xftp5为例

image.png 运行命令 tar -zxvf datax.tar.gz -C /opt/module 解压到指定目录

1693475925284.png

image.png Datax目前支持读取的数据源

image.png 如果没有安装安装Python运行 sudo yum install python2.7 python2.7-devel python2.7-pip

接下来运行 运行 python bin/datax.py ./job/job.json 查看示例模板(这里是最常用的命令)


DataX (DATAX-OPENSOURCE-3.0), From Alibaba !
Copyright (C) 2010-2017, Alibaba Group. All Rights Reserved.


2023-08-30 22:22:28.326 [main] INFO  MessageSource - JVM TimeZone: GMT+08:00, Locale: zh_CN
2023-08-30 22:22:28.329 [main] INFO  MessageSource - use Locale: zh_CN timeZone: sun.util.calendar.ZoneInfo[id="GMT+08:00",offset=28800000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
2023-08-30 22:22:28.469 [main] INFO  VMInfo - VMInfo# operatingSystem class => sun.management.OperatingSystemImpl
2023-08-30 22:22:28.476 [main] INFO  Engine - the machine info  => 

	osInfo:	Linux amd64 3.10.0-1160.80.1.el7.x86_64
	jvmInfo:	Oracle Corporation 1.8 25.381-b09
	cpu num:	1

	totalPhysicalMemory:	-0.00G
	freePhysicalMemory:	-0.00G
	maxFileDescriptorCount:	-1
	currentOpenFileDescriptorCount:	-1

	GC Names	[Copy, MarkSweepCompact]

	MEMORY_NAME                    | allocation_size                | init_size                      
	Eden Space                     | 273.06MB                       | 273.06MB                       
	Code Cache                     | 240.00MB                       | 2.44MB                         
	Survivor Space                 | 34.13MB                        | 34.13MB                        
	Compressed Class Space         | 1,024.00MB                     | 0.00MB                         
	Metaspace                      | -0.00MB                        | 0.00MB                         
	Tenured Gen                    | 682.69MB                       | 682.69MB                       


2023-08-30 22:22:28.511 [main] INFO  Engine - 
{
	"setting":{
		"speed":{
			"channel":1
		},
		"errorLimit":{
			"record":0,
			"percentage":0.02
		}
	},
	"content":[
		{
			"reader":{
				"name":"streamreader",
				"parameter":{
					"column":[
						{
							"value":"DataX",
							"type":"string"
						},
						{
							"value":19890604,
							"type":"long"
						},
						{
							"value":"1989-06-04 00:00:00",
							"type":"date"
						},
						{
							"value":true,
							"type":"bool"
						},
						{
							"value":"test",
							"type":"bytes"
						}
					],
					"sliceRecordCount":100000
				}
			},
			"writer":{
				"name":"streamwriter",
				"parameter":{
					"print":false,
					"encoding":"UTF-8"
				}
			}
		}
	]
}

2023-08-30 22:22:28.562 [main] INFO  PerfTrace - PerfTrace traceId=job_-1, isEnable=false
2023-08-30 22:22:28.562 [main] INFO  JobContainer - DataX jobContainer starts job.
2023-08-30 22:22:28.564 [main] INFO  JobContainer - Set jobId = 0
2023-08-30 22:22:28.633 [job-0] INFO  JobContainer - jobContainer starts to do prepare ...
2023-08-30 22:22:28.634 [job-0] INFO  JobContainer - DataX Reader.Job [streamreader] do prepare work .
2023-08-30 22:22:28.634 [job-0] INFO  JobContainer - DataX Writer.Job [streamwriter] do prepare work .
2023-08-30 22:22:28.634 [job-0] INFO  JobContainer - jobContainer starts to do split ...
2023-08-30 22:22:28.634 [job-0] INFO  JobContainer - Job set Channel-Number to 1 channels.
2023-08-30 22:22:28.635 [job-0] INFO  JobContainer - DataX Reader.Job [streamreader] splits to [1] tasks.
2023-08-30 22:22:28.635 [job-0] INFO  JobContainer - DataX Writer.Job [streamwriter] splits to [1] tasks.
2023-08-30 22:22:28.699 [job-0] INFO  JobContainer - jobContainer starts to do schedule ...
2023-08-30 22:22:28.704 [job-0] INFO  JobContainer - Scheduler starts [1] taskGroups.
2023-08-30 22:22:28.707 [job-0] INFO  JobContainer - Running by standalone Mode.
2023-08-30 22:22:28.729 [taskGroup-0] INFO  TaskGroupContainer - taskGroupId=[0] start [1] channels for [1] tasks.
2023-08-30 22:22:28.732 [taskGroup-0] INFO  Channel - Channel set byte_speed_limit to -1, No bps activated.
2023-08-30 22:22:28.732 [taskGroup-0] INFO  Channel - Channel set record_speed_limit to -1, No tps activated.
2023-08-30 22:22:28.751 [taskGroup-0] INFO  TaskGroupContainer - taskGroup[0] taskId[0] attemptCount[1] is started
2023-08-30 22:22:28.962 [taskGroup-0] INFO  TaskGroupContainer - taskGroup[0] taskId[0] is successed, used[215]ms
2023-08-30 22:22:28.963 [taskGroup-0] INFO  TaskGroupContainer - taskGroup[0] completed it's tasks.
2023-08-30 22:22:38.752 [job-0] INFO  StandAloneJobContainerCommunicator - Total 100000 records, 2600000 bytes | Speed 253.91KB/s, 10000 records/s | Error 0 records, 0 bytes |  All Task WaitWriterTime 0.087s |  All Task WaitReaderTime 0.099s | Percentage 100.00%
2023-08-30 22:22:38.752 [job-0] INFO  AbstractScheduler - Scheduler accomplished all tasks.
2023-08-30 22:22:38.752 [job-0] INFO  JobContainer - DataX Writer.Job [streamwriter] do post work.
2023-08-30 22:22:38.753 [job-0] INFO  JobContainer - DataX Reader.Job [streamreader] do post work.
2023-08-30 22:22:38.753 [job-0] INFO  JobContainer - DataX jobId [0] completed successfully.
2023-08-30 22:22:38.754 [job-0] INFO  HookInvoker - No hook invoked, because base dir not exists or is a file: /opt/module/datax/hook
2023-08-30 22:22:38.755 [job-0] INFO  JobContainer - 
	 [total cpu info] => 
		averageCpu                     | maxDeltaCpu                    | minDeltaCpu                    
		-1.00%                         | -1.00%                         | -1.00%
                        

	 [total gc info] => 
		 NAME                 | totalGCCount       | maxDeltaGCCount    | minDeltaGCCount    | totalGCTime        | maxDeltaGCTime     | minDeltaGCTime     
		 Copy                 | 0                  | 0                  | 0                  | 0.000s             | 0.000s             | 0.000s             
		 MarkSweepCompact     | 0                  | 0                  | 0                  | 0.000s             | 0.000s             | 0.000s             

2023-08-30 22:22:38.756 [job-0] INFO  JobContainer - PerfTrace not enable!
2023-08-30 22:22:38.756 [job-0] INFO  StandAloneJobContainerCommunicator - Total 100000 records, 2600000 bytes | Speed 253.91KB/s, 10000 records/s | Error 0 records, 0 bytes |  All Task WaitWriterTime 0.087s |  All Task WaitReaderTime 0.099s | Percentage 100.00%
2023-08-30 22:22:38.757 [job-0] INFO  JobContainer - 
任务启动时刻                    : 2023-08-31 06:22:28
任务结束时刻                    : 2023-08-31 06:22:38
任务总计耗时                    :                 10s
任务平均流量                    :          253.91KB/s
记录写入速度                    :          10000rec/s
读出记录总数                    :              100000
读写失败总数                    :                   0

直观的看到读写失败总数

image.png

image.png

image.png

日常工作中尽量不要使用 “ * ”

以 SQLserver 同步到 mysql 为例

运行命令:[root@localhost datax]# vim job/(自定义名称).json 将模板编辑后插入json

运行命令:[root@localhost datax]# bin/datax.py -r sqlserverreader -w mysqlwriter 取得模板

  "job": {
    "content": [
      {
        "reader": {
          "name": "sqlserverreader",
          "parameter": {
            "column": [
             "*"
            ],
            "connection": [
              {
                "jdbcUrl": [
                  "jdbc:sqlserver://数据库IP地址:1433;DatabaseName=数据库名称"
                ],
                "table": [
                  "表名"
                ]
              }
            ],
            "password": "密码",
            "username": "用户名"
          }
        },
        "writer": {
          "name": "mysqlwriter",
          "parameter": {
            "column": [
             "*"
            ],
            "connection": [
              {
                "jdbcUrl": "jdbc:mysql://数据库IP地址:3306/数据库名?useSSL=false&useUnicode=true&characterEncoding=utf8",
                "table": [
                  "表名"
                ]
              }
            ],
            "password": "密码",
            "preSql": [],
            "session": [],
            "username": "用户名",
            "writeMode": "insert"
          }
        }
      }
    ],
    "setting": {
      "speed": {
        "channel": "1" // 并发为1
      }
    }
  }
}

运行: [root@localhost datax]# bin/datax.py job/自定义的名称.json

执行结果:

2023-08-30 22:51:58.792 [job-0] INFO  StandAloneJobContainerCommunicator - Total 3 records, 102 bytes | Speed 10B/s, 0 records/s | Error 0 records, 0 bytes |  All Task WaitWriterTime 0.000s |  All Task WaitReaderTime 0.000s | Percentage 100.00%
2023-08-30 22:51:58.792 [job-0] INFO  AbstractScheduler - Scheduler accomplished all tasks.
2023-08-30 22:51:58.792 [job-0] INFO  JobContainer - DataX Writer.Job [mysqlwriter] do post work.
2023-08-30 22:51:58.793 [job-0] INFO  JobContainer - DataX Reader.Job [sqlserverreader] do post work.
2023-08-30 22:51:58.793 [job-0] INFO  JobContainer - DataX jobId [0] completed successfully.
2023-08-30 22:51:58.793 [job-0] INFO  HookInvoker - No hook invoked, because base dir not exists or is a file: /opt/module/datax/hook
2023-08-30 22:51:58.794 [job-0] INFO  JobContainer - 
	 [total cpu info] => 
		averageCpu                     | maxDeltaCpu                    | minDeltaCpu                    
		-1.00%                         | -1.00%                         | -1.00%
                        

	 [total gc info] => 
		 NAME                 | totalGCCount       | maxDeltaGCCount    | minDeltaGCCount    | totalGCTime        | maxDeltaGCTime     | minDeltaGCTime     
		 Copy                 | 0                  | 0                  | 0                  | 0.000s             | 0.000s             | 0.000s             
		 MarkSweepCompact     | 1                  | 1                  | 1                  | 0.045s             | 0.045s             | 0.045s             

2023-08-30 22:51:58.794 [job-0] INFO  JobContainer - PerfTrace not enable!
2023-08-30 22:51:58.795 [job-0] INFO  StandAloneJobContainerCommunicator - Total 3 records, 102 bytes | Speed 10B/s, 0 records/s | Error 0 records, 0 bytes |  All Task WaitWriterTime 0.000s |  All Task WaitReaderTime 0.000s | Percentage 100.00%
2023-08-30 22:51:58.795 [job-0] INFO  JobContainer - 
任务启动时刻                    : 2023-08-31 06:51:46
任务结束时刻                    : 2023-08-31 06:51:58
任务总计耗时                    :                 12s
任务平均流量                    :               10B/s
记录写入速度                    :              0rec/s
读出记录总数                    :                   3
读写失败总数                    :                   0


查看数据库

image.png --------------------------OK--------------------------------

DataX使用优化

优化1:提升每个channel的速度

在 DataX内部对每个Channel 会有严格的速度控制,分两种,一种是控制每秒同步的记录数,另外一种是每秒同步的字节数,默认的速度限制是 1MB/s,可以根据具体硬件情况设置这个 byte 速度或者 record 速度,一般设置 byte 速度,比如:我们可以把单个 Channel的速度上限配置为5MB。

优化2:提升DataX Job 内 Channel并发数

优化3:提高JVM 堆内存

当提升 DataXJob 内 Chanmel 并发数时,内存的占用会显著增加,因为 DataX 作为数据交换通道,在内存中会缓存较多的数据。例如 Channel 中会有一个 Buffer,作为临时的数据交换的缓冲区,而在部分 Reader 和 Writer 的中,也会存在一些 Buffer,为了防止 OOM 等错误,调大JVM的堆内存。 建议将内存设置为 4G 或者 8G,这个也可以根据实际情况来调整。 调整JVM xms xx 参数的两种方式:一种是直接更改dataxpy 脚本;另一种是在启动的时候,加上对应的参数,如下: python datax/bin/datax.py --jvm="-Xms8G -Xmx8G"XXX.json