最近使用datax进行mysql数据同步,遇到不少问题,记录下来以做警示。
源码:
gittee传送门
工具包:
DataX下载地址
ps:建议下载源码。因为毕竟可以改。
-
工具部署
-
方法一、直接下载DataX工具包:DataX下载地址
下载后解压至本地某个目录,进入bin目录,即可运行同步作业:
$ cd {YOUR_DATAX_HOME}/bin $ python datax.py {YOUR_JOB.json}
自检脚本:
python {YOUR_DATAX_HOME}/bin/datax.py {YOUR_DATAX_HOME}/job/job.json -
方法二、下载DataX源码,自己编译:DataX源码
(1)、下载DataX源码:
$ git clone git@github.com:alibaba/DataX.git
(2)、通过maven打包:
$ cd {DataX_source_code_home} $ mvn -U clean package assembly:assembly -Dmaven.test.skip=true
打包成功,日志显示如下:
[INFO] BUILD SUCCESS [INFO] ----------------------------------------------------------------- [INFO] Total time: 08:12 min [INFO] Finished at: 2015-12-13T16:26:48+08:00 [INFO] Final Memory: 133M/960M [INFO] -----------------------------------------------------------------
-
至此dataX插件已经准备好,还需要以下环境
- JDK(1.8以上,推荐1.8)
- Python(推荐Python2.6.X)
- Apache Maven 3.x (Compile DataX)
准备操作完成后,直接上java代码
@Value(value = "E:\\study\\DataX\\target\\datax\\datax\\bin\\datax.py")
private String dataxPath;
//任务文件夹的路径
@Value("E:\\study\\job\\")
private String jsonPath;
//python路径
@Value(value = "E:\\Program Files\\python\\python.exe")
private String pythonPath;
@Test
public void datax() {
doTask();
}
private void doTask(){
File[] files=getFileList();
for(File f:files){
String cmd = pythonPath+" "+dataxPath+" "+f.getAbsolutePath();
try {
Process process = Runtime.getRuntime().exec(cmd);
//返回信息写入流用控制台打出来
//此处转码,不然控制台中文乱码
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream(),"utf-8"));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
process.waitFor();
}catch (Exception e){
log.error(e.getMessage());
}
}
}
private File[] getFileList(){
File file=new File(jsonPath);
File[] files=file.listFiles((File f)->f.getName().endsWith(".json"));
return files;
}
json文件
{
"core":{"transport":{"channel":{"speed":{"byte":104857600}}}},
"job": {
"setting": {
"speed": {
"byte": 1048576,
"channel": "5"
}
},
"content": [
{
"reader": {
"name": "mysqlreader",
"parameter": {
"username": "root",
"password": "123456",
"column": [
"id",
"remark"
],
"connection": [
{
"table": [
"test_datax_source"
],
"jdbcUrl": [
"jdbc:mysql://localhost:3306/test"
]
}
]
}
},
"writer": {
"name": "mysqlwriter",
"parameter": {
"username": "root",
"password": "123456",
"column": [
"id",
"remark"
],
"connection": [
{
"table": [
"test_datax_target"
],
"jdbc:mysql://localhost:3306/test"
}
]
}
}
}
]
}
}
问题1
这个问题网上有很多帖子不多说,mysql数据驱动问题。下载的datax默认驱动为com.mysql.jdbc.Driver
第一步,修改pom文件mysql版本。第二步,全局修改com.mysql.jdbc.Driver。
这是个衍生问题,修改了数据库驱动以后,发现报这个问题。网上没找到解释,自己操作了一会,得出一个简单结论(有问题欢迎指出~~):
数据源版本com.mysql.jdbc.Driver使用 convertToNull;
数据源版本com.mysql.cj.jdbc.Driver使用 CONVERT_TO_NULL
问题2
在有总bps限速条件下,单个channel的bps值不能为空,也不能为非正数
解决:报文很明显,我们bps这个字段没有设置。我们看源码↓:
// 在byte流控情况下,单个Channel流量最大值必须设置,否则报错!
Long channelLimitedByteSpeed = this.configuration
.getLong(CoreConstant.DATAX_CORE_TRANSPORT_CHANNEL_SPEED_BYTE);
if (channelLimitedByteSpeed == null || channelLimitedByteSpeed <= 0) {
throw DataXException.asDataXException(
FrameworkErrorCode.CONFIG_ERROR,
"在有总bps限速条件下,单个channel的bps值不能为空,也不能为非正数");
}
CoreConstant.DATAX_CORE_TRANSPORT_CHANNEL_SPEED_BYTE这个值为空。那么看一下这个值是个什么↓
public static final String DATAX_CORE_TRANSPORT_CHANNEL_SPEED_BYTE = "core.transport.channel.speed.byte";
那么,我们给json文件的job同级加上对应的byte,问题解决:
"core":{"transport":{"channel":{"speed":{"byte":104857600}}}}
问题3
这种一般是写错东西了,像我手残表名写成test-ss,泪遁
问题4
这个类似问题2
boolean isChannelLimit = (this.configuration.getInt(
CoreConstant.DATAX_JOB_SETTING_SPEED_CHANNEL, 0) > 0);
if (isChannelLimit) {
this.needChannelNumber = this.configuration.getInt(
CoreConstant.DATAX_JOB_SETTING_SPEED_CHANNEL);
LOG.info("Job set Channel-Number to " + this.needChannelNumber
+ " channels.");
return;
}
throw DataXException.asDataXException(
FrameworkErrorCode.CONFIG_ERROR,
"Job运行速度必须设置");
public static final String DATAX_JOB_SETTING_SPEED_CHANNEL = "job.setting.speed.channel";
在job下新增setting
"setting": {
"speed": {
"byte": 1048576,
"channel": "5"
}
},
``