来源:https://blog.itpub.net/70027827/viewspace-2992468/
用DataX导数据到Clickhouse遇到的坑
数据分析 作者:大数据技术前线 时间:2023-11-02 10:26:45 1541 0
来源:安瑞哥是码农
这两天在帮一个项目部署 Clickhouse (下称CK),并且需要将上游的数据给导入到其中。
由于只是一个单纯的上游数据导入,暂时还不涉及到对数据的计算和处理,所以就想着用一个合适的数据导入工具来满足这个需求。
于是,我就想到了DataX(因为之前用过的CK外部表+物化视图的方式突然在当前环境下哑火了)。
原本以为就是一个简单的数据传输,用这个号称功能强大的传输工具,应该手到擒来才对,但不曾想,这玩意的坑不少。
- 下载和部署
由于第一次在文章中写关于DataX的内容,先简单聊下我对这个工具的认识。
DataX是一个以Python语言为外壳,Java语言为核心的多线程数据传输软件,它的一大特点是,对数据源的读取,以及向数据目的地的写入,是通过一个个「插件」来实现的。
所以对于DataX来说,想要实现一个完整的数据传输功能,就必须包含两大部分。
第一部分为DataX的软件主体(DataX工具包):
这个是使用 DataX 的基础,通过官方提供的下载地址,下载下来后是一个压缩包。
解压后,跟很多普通软件一样目录结构是这样的:
这部分包含了DataX的核心启动程序,以及数据传输时需要依赖的基础环境。
第二个为插件部分:
这个插件,可以根据你不同的数据存储(比如各种数据库,文件系统等)的版本、特点来进行编码(实现特定的接口),最后打包成DataX规范的目录结构,然后将其上传到对应的 plugin 目录中来实现对各种存储软件的支持。
其中,这个插件又分为 reader 插件,和 writer 插件两部分。
只不过,并不是所有的插件都需要你去开发,对于DataX来说,它原本就内置了一些比较常用的reader 插件以及 writer 插件,直接用就可以。
- 编译CK的writer插件源码
由于本次我的需求是将读取到的MySQL数据源,给写入到CK中,也就是说,在我的 DataX 里,分别要有一个mysql的reader插件,以及一个ck的writer插件。
但是,对于从官网下载的原始版本的DataX来说,目前只有mysql的reader插件,而没有CK的writer插件,咋整?
最好的办法:下载源码,适当修改和编译!
虽然在网上也能找到一些CK的writer插件,但这里我不建议,因为很有可能你下载的的插件,是基于老版本的CK开发和编译的,也许并不适用你的场景。
1.1 拉取代码
既然需要对源码做适当修改,第一步当然是要将它拉取到本地的IDE开发环境中。
具体的Git地址为:https://github.com/alibaba/DataX.git (最新的)
拉取到本地IDE之后,由于这个地址包含了所有目前 DataX 支持的 reader 和 writer 插件 module (代码),所以内容就太多了,我们只需要选取本次需要的 CK writer 插件以及相应的必须依赖就可以。
所以,在我的IDE里,会把这些我不需要的 modules 全都给注释掉,整个项目就变成了这样:
1.2 修改对应配置
给这个DataX的插件工程瘦身之后,接下就需要根据前面说的,根据实际CK的版本情况,对配置做适当的修改。
通过查看源码的配置可以知道,DataX的CK插件用的jdbc通信方式,且对应的配置如下:
而我部署的CK为23.xx版本,属于比较新的版本,官方推荐的jdbc版本依赖如下:
所以很显然,需要修改DataX插件依赖的jdbc版本,跟CK官网要求的保持一致,否则会导致数据写入报错。
修改后,通过IDE对这个插件工程进行编译,编译后,得到如下对应的文件和相关目录:
1.3 第1个坑
将上述这个CK writer插件(编译后生成的插件内容)上传到dataX的plugin目录下,再配合我这个配置文件。
{
“job”: {
“setting”: {
“speed”: {
“channel”: 3
},
“errorLimit”: {
“record”: 0,
“percentage”: 0.02
}
},
“content”: [
{
“reader”: {
“name”: “mysqlreader”,
“parameter”: {
“username”: “root”,
“password”: “xxxx”,
“column”: [“id”,“name”],
“splitPk”: “id”,
“connection”: [
{
“table”: [“test”],
“jdbcUrl”: [
“jdbc:mysql://mysql_ip:3306/clickhouse_test”
]
}
]
}
},
“writer”: {
“name”: “clickhousewriter”,
“parameter”: {
“username”: “default”,
“password”: “xxxx”,
“column”:[“id”,“name”],
“connection”: [
{
“jdbcUrl”: “jdbc:ch://ck_ip:8123/default”,
“table”:[“test01”]
}
]
}
}
}
]
}
}
根据模板修改的一个最简单例子
启动对应的数据传输命令:
喜提第一个坑,说这个插件目录下有大量这种以._命名的隐藏文件,然后程序把这个隐藏的文件全部都当成目录了,要去找里面的plugin.json文件。
解决办法就是,删除reader和writer目录下所有以._命名的这些文件。
怎么说呢,这要不是脑子有几个包,应该是想不出这么个设计的。
1.4 第2个坑
以为把上面这个问题解决了就没事了吧,但我还是想简单了,再次启动,就给我扔出这么个破玩意:
从报错中可以明显看出来,它加载了一个过时的CK的jdbc驱动类。
但是我明明在源码的pom文件中,已经给改过来为最新的了啊,为啥它还要去找这个老驱动类呢。
于是我找啊找,找啊找,终于,在CK的插件源码中揪出了这个罪魁祸首。
原来这个JDBC的驱动类,被硬编码在common这个module的一个枚举类中。
找出来后,把它改为新版本的驱动类:
好,编译打包,再试一次。
1.5 第3个坑
再次运行,又报错了。
说当前CK插件写入数据库时不支持LZ4这种压缩方式,好吧,那咱就在依赖里加上它。
在DataX的开发环境,对应的 clickhousewriter 模块pom文件里,加上对应依赖。
再次编译,打包,更换掉之前的CK writer,再试。
终于,它不报错了。