datax避坑记录

本文介绍了使用DataX进行数据库迁移时遇到的问题及解决方案,包括reader和writer名称匹配、1000行数据限制的解决以及如何通过脚本批量迁移数百张表。通过设置querySql和参数传递实现数据量控制和多表同步,提供了一个实用的sh脚本示例。
摘要由CSDN通过智能技术生成

datax避坑记录

​ 先介绍一下datax,dataX 是阿里云 DataWorks数据集成 的开源版本,在阿里巴巴集团内被广泛使用的离线数据同步工具/平台。DataX 实现了包括 MySQL、Oracle、OceanBase、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、Hologres、DRDS 等各种异构数据源之间高效的数据同步功能。

​ 具体的使用方法其实官方的文档写得挺详细的,我就不做多余的重复了,这篇文章主要是写我使用datax时遇到的坑,就拿我之前用datax做mysql数据库的迁移做例子,另,附上官方地址:https://github.com/alibaba/DataX

插件名称对应

​ reader和writer必须对应自己要进行数据同步的对象,比如要进行同步的是mysql数据库,那么job文件中reader和writer对应的name就必须配置为mysqlreader和mysqlwriter。这是一个小细节,因为datax的例子中写的是streamreader和streamwriter,如果复制过来,写job文件的时候忘记改,有时候也会花费些时间去找问题。

1000行限制

​ 了解datax的都知道,用datax时,需要我们自己配置job文件,如下:

{
  "job": {
    "setting": {
      "speed": {
        "channel": 3,
        "byte": 1048576
      },
      "errorLimit": {
        "record": 0,
        "percentage": 0.02
      }
    },
    "content": [
      {
        "reader": {
          "name": "mysqlreader",
          "parameter": {
            "username": "yRjwDFuoPKlqya9h9H2Amg==",
            "password": "6YrK4y3NaUxccEgnoAz8yA==",
            "column": [
              "id",
              "name",
              "age",
              "add_time"
            ],
            "where": "add_time >= ${startTime} and add_time < ${endtTime}",
            "splitPk": "",
            "connection": [
              {
                "table": [
                  "student"
                ],
                "jdbcUrl": [
                  "jdbc:mysql://127.0.0.1:3306/mytest?serverTimezone=Asia/Shanghai&useLegacyDatetimeCode=false&useSSL=false&nullNamePatternMatchesAll=true&useUnicode=true"
                ]
              }
            ]
          }
        },
        "writer": {
          "name": "mysqlwriter",
          "parameter": {
            "username": "yRjwDFuoPKlqya9h9H2Amg==",
            "password": "6YrK4y3NaUxccEgnoAz8yA==",
            "writeMode": "insert",
            "column": [
              "id",
              "name",
              "age",
              "add_time"
            ],
            "connection": [
              {
                "table": [
                  "student"
                ],
                "jdbcUrl": "jdbc:mysql://127.0.0.1:3306/datax_test?serverTimezone=Asia/Shanghai&useLegacyDatetimeCode=false&useSSL=false&nullNamePatternMatchesAll=true&useUnicode=true"
              }
            ]
          }
        }
      }
    ]
  }
}

​ 但是有可能会遇到明明有上万的数据,却只能读取到一千条,为啥呢,有可能是数据库默认限制了一次只能抽取1000条,这个时候可以使用querySql,通过limit解决。

{
  "job": {
    "setting": {
      "speed": {
        "channel": 3,
        "byte": 1048576
      },
      "errorLimit": {
        "record": 0,
        "percentage": 0.02
      }
    },
    "content": [
      {
        "reader": {
          "name": "mysqlreader",
          "parameter": {
            "username": "yRjwDFuoPKlqya9h9H2Amg==",
            "password": "6YrK4y3NaUxccEgnoAz8yA==",
            "column": [
              "id",
              "name",
              "age",
              "add_time"
            ],
            "splitPk": "",
            "connection": [
              {
                "querySql":"select * from student limit 0,100000",
                "jdbcUrl": [
                  "jdbc:mysql://127.0.0.1:3306/mytest?serverTimezone=Asia/Shanghai&useLegacyDatetimeCode=false&useSSL=false&nullNamePatternMatchesAll=true&useUnicode=true"
                ]
              }
            ]
          }
        },
        "writer": {
          "name": "mysqlwriter",
          "parameter": {
            "username": "yRjwDFuoPKlqya9h9H2Amg==",
            "password": "6YrK4y3NaUxccEgnoAz8yA==",
            "writeMode": "insert",
            "column": [
              "id",
              "name",
              "age",
              "add_time"
            ],
            "connection": [
              {
                "table": [
                  "student"
                ],
                "jdbcUrl": "jdbc:mysql://127.0.0.1:3306/datax_test?serverTimezone=Asia/Shanghai&useLegacyDatetimeCode=false&useSSL=false&nullNamePatternMatchesAll=true&useUnicode=true"
              }
            ]
          }
        }
      }
    ]
  }
}

​ 这样,可以一次性可以查询出100000条数据了,因为我是导全表数据,所以where条件也不需要。

批量执行

​ 因为是数据库迁移,一般来说有个几百张表都是基本操作,如果我执行一个表的迁移就要去改一下job文件中的表名岂不是很麻烦吗,所以我去留意了一下datax的配置,发现table的配置是用的[],那感觉这里面应该是支持多表的。

在这里插入图片描述

​ emmm。。。那如果schema结构不一样怎么办,本来我要做的就是把这部分数据迁移到另一个数据库里。所以这里是有点麻烦,但是也不是没有办法解决,这里可以通过一个sh脚本去解决。

​ 首先job文件需要调整一下,表名这些就不能固定死,要通过参数传递进来。因为我可以确定表的字段结构这些都是能一一对应的,column配置我就直接使用的*。

{
  "job": {
    "setting": {
      "speed": {
        "channel": 3,
        "byte": 1048576
      },
      "errorLimit": {
        "record": 0,
        "percentage": 0.02
      }
    },
    "content": [
      {
        "reader": {
          "name": "mysqlreader",
          "parameter": {
            "username": "yRjwDFuoPKlqya9h9H2Amg==",
            "password": "6YrK4y3NaUxccEgnoAz8yA==",
            "column": ["*"],
            "splitPk": "",
            "connection": [
              {
                "querySql":"select * from ${source_table_name} limit 0,100000",
                "jdbcUrl": [
                  "${source_db}"
                ]
              }
            ]
          }
        },
        "writer": {
          "name": "mysqlwriter",
          "parameter": {
            "username": "yRjwDFuoPKlqya9h9H2Amg==",
            "password": "6YrK4y3NaUxccEgnoAz8yA==",
            "writeMode": "insert",
            "column": ["*"],
            "connection": [
              {
                "table": [
                  "${target_table_name}"
                ],
                "jdbcUrl": "${target_db}"
              }
            ]
          }
        }
      }
    ]
  }
}

​ 说明一下sh脚本,我的datax安装目录:/data/lxf/datax,我写的job文件名为datasync.json,就放在datax的job目录下,tables.txt是我存放所有需要导的表名的文件,为了方便我也同样放在datax的job目录下,且两个数据库需要迁移的表的表名都是一样的。所以,最终sh脚本如下:

table_list='/data/lxf/datax/job/tables.txt'
exec_path='/data/lxf/datax/bin/datax.py'
source_db='jdbc:mysql://127.0.0.1:3306/mytest?serverTimezone=Asia/Shanghai&useLegacyDatetimeCode=false&useSSL=false&nullNamePatternMatchesAll=true&useUnicode=true'
target_db='jdbc:mysql://127.0.0.1:3306/datax_test?serverTimezone=Asia/Shanghai&useLegacyDatetimeCode=false&useSSL=false&nullNamePatternMatchesAll=true&useUnicode=true'
for table_name in cat $table_list
do
	python $exec_path -p "-Dsource_table_name=$table_name -Dtarget_table_name=$table_name -Dsource_db=$source_db -Dtarget_db=$target_db" /data/lxf/datax/job/datasync.json
done

​ tables.txt的内容如下,有多少表写多少就行,一个表名一行:

student
user_info
role_info

以上就是我第一次使用datax遇到的一些坑,也用自己的办法解决了,希望对大家有用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

佛祖保佑永不宕机

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

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

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

打赏作者

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

抵扣说明:

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

余额充值