在最近接触到的一个case里面,须要把db2的数据迁移至oracle,客户可接收的停机时间为3小时。mysql
一说到停机时间,你们第一时间想到Oracle公司的GoldenGate实时同步工具。但在测试过程当中发现,因为没法提早检查,并且初始化时间好久等问题,致使咱们最后不得不放弃使用这一神器。git
既然OGG不能使用,那能传统导出文本再用sql load导入,那是否可行呢?根据以往的经验,只要数据一落地就存在乱码,数据错位等问题,因为没法进行hash对帐,数据质量根本没法保证。github
我司的某平台软件,直接从内存中进行数据转换,让咱们看到一大但愿。因为列的顺序不一,没法知足部分需求,只能又放弃这一神器。sql
就在此时,提出了一个开源软件——DATAX。数据库
DataX 是阿里巴巴集团内被普遍使用的离线数据同步工具/平台,实现包括 MySQL、Oracle、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、DRDS 等各类异构数据源之间高效的数据同步功能。数组
注意,这里说的是离线数据同步工具,就是必须得停机以后再进行数据同步。那DATAX究竟支持哪些数据库进行数据同步呢?如下是GitHub提供的列表:服务器
类型网络 |
数据源多线程 |
Reader(读)架构 |
Writer(写) |
文档 |
RDBMS 关系型数据库 |
MySQL |
√ |
√ |
|
Oracle |
√ |
√ |
||
SQLServer |
√ |
√ |
||
PostgreSQL |
√ |
√ |
||
DRDS |
√ |
√ |
||
通用RDBMS(支持全部关系型数据库) |
√ |
√ |
||
阿里云数仓数据存储 |
ODPS |
√ |
√ |
|
ADS |
√ |
|||
OSS |
√ |
√ |
||
OCS |
√ |
√ |
||
NoSQL数据存储 |
OTS |
√ |
√ |
|
Hbase0.94 |
√ |
√ |
||
Hbase1.1 |
√ |
√ |
||
MongoDB |
√ |
√ |
||
Hive |
√ |
√ |
||
无结构化数据存储 |
TxtFile |
√ |
√ |
|
FTP |
√ |
√ |
||
HDFS |
√ |
√ |
||
Elasticsearch |
√ |
在这个case里面,咱们使用datax3.0的核心架构。DataX 3.0 开源版本支持单机多线程模式完成同步做业运行,按一个DataX做业生命周期的时序图,从总体架构设计很是简要说明DataX各个模块相互关系。
JOB经过配置对同步整个过程进行管控。
"job": { "setting": { "speed": { "byte": 1048576 }, "errorLimit": { "record": 0, "percentage": 0.02 } },
speed为同步速度限制参数,这里有三个参数channel、record和byte。
channel:管道数,能够理解为并行数,需与splitPk一同使用,不然无效果。
record:每次同步多少条数据,取record和byte中的最小值
byte:每次同步多少字节数据,取record和byte中的最小值
errorLimit为错误数据限制,这里有两个参数record和percentage,指当异常数据达到多少时同步取消,取record和percentage的最小值。
RDBMSReader经过JDBC链接器链接到远程的RDBMS数据库,并根据用户配置的信息生成查询SELECT SQL语句并发送到远程RDBMS数据库,并将该SQL执行返回结果使用DataX自定义的数据类型拼装为抽象的数据集,并传递给下游Writer处理。
对于用户配置Table、Column、Where的信息,RDBMSReader将其拼接为SQL语句发送到RDBMS数据库;对于用户配置querySql信息,RDBMS直接将其发送到RDBMS数据库。
DB2被阿里分为通用RDBMS的范畴。配置一个从RDBMS数据库同步抽取数据做业样例:
"content": [ { "reader": { "name": "rdbmsreader", "parameter": { "username": "xxx", "password": "xxx", "column": [ "id", "name" ], "splitPk": "pk", "connection": [ { "table": [ "table" ], "jdbcUrl": [ "jdbc:dm://ip:port/database" ] } ], "fetchSize": 1024, "where": "1 = 1" } },
username
源数据库的用户名
password
源数据库的密码
encoding
数据库字符集,GBK,UTF8等
column
所配置的表中须要同步的列名集合,使用JSON的数组描述字段信息。用户使用表明默认使用全部列配置,例如['']。
支持列裁剪,即列能够挑选部分列进行导出。
支持列换序,即列能够不按照表schema信息进行导出。
支持常量配置,用户须要按照JSON格式: ["id", "1", "'bazhen.csy'", "null", "to_char(a + 1)", "2.3" , "true"] id为普通列名,1为整形数字常量,'bazhen.csy'为字符串常量,null为空指针,to_char(a + 1)为表达式,2.3为浮点数,true为布尔值。
Column必须显示填写,不容许为空!
splitPk
RDBMSReader进行数据抽取时,若是指定splitPk,表示用户但愿使用splitPk表明的字段进行数据分片,DataX所以会启动并发任务进行数据同步,这样能够大大提供数据同步的效能。
推荐splitPk用户使用表主键,由于表主键一般状况下比较均匀,所以切分出来的分片也不容易出现数据热点。
目前splitPk仅支持整形数据切分,不支持浮点、字符串型、日期等其余类型。若是用户指定其余非支持类型,RDBMSReader将报错!
注意:这里并不是只能是主键,拥有惟一约束的列也可。
table
所选取的须要同步的表名
jdbcUrl
描述的是到对端数据库的JDBC链接信息,jdbcUrl按照RDBMS官方规范,并能够填写链接附件控制信息。请注意不一样的数据库jdbc的格式是不一样的,DataX会根据具体jdbc的格式选择合适的数据库驱动完成数据读取。
fetchSize
该配置项定义了插件和数据库服务器端每次批量数据获取条数,该值决定了DataX和服务器端的网络交互次数,可以较大的提高数据抽取性能。
注意,该值最大建议值为2048。
where
筛选条件,RDBMSReader根据指定的column、table、where条件拼接SQL,并根据这个SQL进行数据抽取。例如在作测试时,能够将where条件指定为limit 10;在实际业务场景中,每每会选择当天的数据进行同步,能够将where条件指定为gmt_create > $bizdate 。
小结:
我司某产品不被咱们选用主要是配置中不存在column和where两个条件的参数,没法对部分数据进行过滤。
OracleWriter 插件实现了写入数据到 Oracle 主库的目的表的功能。在底层实现上, OracleWriter 经过 JDBC 链接远程 Oracle 数据库,并执行相应的 insert into ... sql 语句将数据写入 Oracle,内部会分批次提交入库。
OracleWriter 面向ETL开发工程师,他们使用 OracleWriter 从数仓导入数据到 Oracle。同时 OracleWriter 亦能够做为数据迁移工具为DBA等用户提供服务。
OracleWriter 经过 DataX 框架获取 Reader 生成的协议数据,根据你配置生成相应的SQL语句
insert into...
(当主键/惟一性索引冲突时会写不进去冲突的行) 对于使用datax同步到oracle的表,建议删除主键和惟一索引,数据校验完成后再进行重建。
"writer": { "name": "oraclewriter", "parameter": { "username": "root", "password": "root", "column": [ "id", "name" ], "preSql": [ "delete from test" ], "connection": [ { "jdbcUrl": "jdbc:oracle:thin:@[HOST_NAME]:PORT:[DATABASE_NAME]", "table": [ "test" ] } ] }
username
目的数据库的用户名
password
目的数据库的密码
encoding
数据库字符集
batchSize
一次性批量提交的记录数大小,该值能够极大减小DataX与Oracle的网络交互次数,并提高总体吞吐量。最大只能设置为1024
column
的表须要写入数据的字段,字段之间用英文逗号分隔。例如: "column": ["id","name","age"]。若是要依次写入所有列,使用表示, 例如: "column": [""]
preSql
执行语句时会先检查是否存在若存在,根据条件删除
jdbcUrl
目的数据库的 JDBC 链接信息
table
目的表的表名称。支持写入一个或者多个表。当配置为多张表时,必须确保全部表结构保持一致。
数据转换最高速度一条管道13000rec/s+,经过where手工对部分字段拆分进程进行同步,同步536250880rec大约须要90分钟(容量300GB)的时间。