最近遇到实际项目中从Oracle导大量数据到Clickhouse的需求,本来想给项目团队减低难度,用Airbyte进行数据调度,而且试用了下Airbyte,这个平台可是个新鲜玩意,用CH这么久,第一次碰到可以不用提前在CH里面建表,就能直接拉取的工具,它会自己建库建表,而且默认表引擎就是强大的mergetree,而且所有工具全部基于docker容器,环境隔离,建议尝试下。
Airbyte的官网地址:Introduction | Airbyte Documentation
按照官网的指导,两种方式可以构建起容器集群:
方式一:
git clone https://github.com/airbytehq/airbyte.git
cd airbyte
docker-compose up
方式二:
从GitHub - airbytehq/airbyte: Airbyte is an open-source EL(T) platform that helps you replicate your data in your warehouses, lakes and databases.只下载两个文件:docker-compose.yaml和.env 注意env前面有个点,然后执行docker-compose up指令即可。airbyte的版本控制在.env里。
两种方法起的时候都要连接互联网,系统自动从dockerHub拉取相应的容器,一大堆容器。
我从Oracle拉取到了CH,界面如上图,而且支持定时机构和增量拉取,经常拉数据的话还是很方便的。不过注意Oracle的连接只支持SID方式,不支持Service_name方式,这一点有时候有点头疼。
airbyte启动后会有6个常驻容器,其他容器用完就会销毁。
如果想离线部署的话,可以在能连接互联网的机器上跑通全流程后,把所有相关的容器用docker save -o 命令打包出去,到了离线机器上用docker load -i 命令全部加载进来,同时把airbyte这个文件夹拷贝到目标机器上,执行docker-compose up指令即可。
我这个就是在自己电脑上跑通后,移植到公司测试环境的,测试环境没法连接互联网,但不影响。
OK,言归正传。
可以看到,上面这种方法太庞大笨重了,其他的工具Waterdrop需要spark的支持,更庞大;DataX需要自己编译,官方的版本不支持Clickhouse,无奈咱也不太懂Java,maven啥的,放弃;kettel已经过时了,而且慢,不考虑。抛开现有的所有工具,有没有其他方法能够调度数据的。答案是有,就在官网,请看:
也就是说,你只需要Clickhouse JDBC Bridge和相应的JDBC驱动就能完成,而且还能将相应个数据库与CH融合到一起,用CH做代理,来操作相应的数据库,进行数据分析,关键速度还能比原始数据库快,很神奇吧。开搞
第一步:下载JDBC Bridge
把上面地址直接粘贴到浏览器下载。
第二步:下载Oracle JDBC,我直接从dbeaver的驱动目录拷贝的,你也可以去Oracle官网下载。
第三步:安装openJDK
Java Downloads | Oracle 点击链接,从Oracle下载JDK18 linux版本
我下载的是RPM格式的,你可以根据自己的需求下载相应版本。拷贝到服务器,执行命令离线安装:
rpm -ivh jdk-18_linux-x64_bin.rpm
成功如下:
[root@t3-tkias-0025-app02 ~]# java -version
java version "18.0.1.1" 2022-04-22
Java(TM) SE Runtime Environment (build 18.0.1.1+2-6)
Java HotSpot(TM) 64-Bit Server VM (build 18.0.1.1+2-6, mixed mode, sharing)
第四步:配置驱动
cd ~/clickhouse-jdbc-bridge
mkdir -p config/datasources
touch config/datasources/myoracle.json
我的绝对路径如下:
[root@t3-tkias-0025-app02 clickhouse-jdbc-bridge]# pwd
/data/ch/conf/clickhouse-jdbc-bridge
[root@t3-tkias-0025-app02 clickhouse-jdbc-bridge]# ll
总用量 10492
-rw-r--r-- 1 useradmin useradmin 10737611 5月 30 09:35 clickhouse-jdbc-bridge-2.0.7-shaded.jar
drwxr-xr-x 3 root root 4096 5月 30 09:40 config
把如下内容复制进myoracle.json
{
"myoracle": {
"driverUrls": ["/data/ch/conf/clickhouse-jdbc-bridge/config/datasources/driver/ojdbc8-12.2.0.1.jar"],
"jdbcUrl": "jdbc:oracle:thin:@//localhost:1521/orclpdb1",
"username": "XXXXX",
"password": "XXXXX",
"driverClassName": "oracle.jdbc.driver.OracleDriver",
"connectionTestQuery":""
}
}
把oracle的JDBC驱动拷贝到"driverUrls"参数指定的目录中。
"connectionTestQuery"参数一定要置空,不然它会有个测试select 1,但是Oracle的语法好像不支持这样,然后就报错了。
注意:这样配置对时间类型的列会有问题,解决方案请参考我的另一篇博文。http://t.csdn.cn/nvBP9http://t.csdn.cn/nvBP9
可配置参数及其定义可以从如下地址查看:
clickhouse-jdbc-bridge/datasource.jschema at master · ClickHouse/clickhouse-jdbc-bridge · GitHub
第五步:启动Java进程
切换到clickhouse-jdbc-bridge目录。执行如下命令
java -jar clickhouse-jdbc-bridge-2.0.7-shaded.jar
直接执行上面的命令,在关闭窗口后,进程自动结束了。如果想进程常驻,执行如下命令:
nohup java -jar clickhouse-jdbc-bridge-2.0.7-shaded.jar &
执行过程如下:
[root@t3-tkias-0025-app02 clickhouse-jdbc-bridge]# java -jar clickhouse-jdbc-bridge-2.0.7-shaded.jar
5月 30, 2022 3:03:28 下午 ru.yandex.clickhouse.jdbcbridge.core.Utils loadJsonFromFile
信息: Loading JSON from file [config/vertx.json]...
5月 30, 2022 3:03:28 下午 ru.yandex.clickhouse.jdbcbridge.core.Utils loadJsonFromFile
警告: Failed to load JSON from file config/vertx.json
5月 30, 2022 3:03:52 下午 ru.yandex.clickhouse.jdbcbridge.core.Utils loadJsonFromFile
信息: Loading JSON from file [config/server.json]...
5月 30, 2022 3:03:52 下午 ru.yandex.clickhouse.jdbcbridge.core.Utils loadJsonFromFile
警告: Failed to load JSON from file config/server.json
5月 30, 2022 3:03:55 下午 ru.yandex.clickhouse.jdbcbridge.internal.vertx.core.impl.BlockedThreadChecker
警告: Thread Thread[vert.x-eventloop-thread-0,5,main]=Thread[vert.x-eventloop-thread-0,5,main] has been blocked for 2704 ms, time limit is 2000 ms
5月 30, 2022 3:03:56 下午 ru.yandex.clickhouse.jdbcbridge.internal.vertx.core.impl.BlockedThreadChecker
警告: Thread Thread[vert.x-eventloop-thread-0,5,main]=Thread[vert.x-eventloop-thread-0,5,main] has been blocked for 3704 ms, time limit is 2000 ms
5月 30, 2022 3:03:56 下午 ru.yandex.clickhouse.jdbcbridge.JdbcBridgeVerticle registerConfigLoader
信息: Start to monitor configuration file(s) at [config/datasources]
5月 30, 2022 3:03:56 下午 ru.yandex.clickhouse.jdbcbridge.JdbcBridgeVerticle registerConfigLoader
信息: Start to monitor configuration file(s) at [config/schemas]
5月 30, 2022 3:03:56 下午 ru.yandex.clickhouse.jdbcbridge.JdbcBridgeVerticle registerConfigLoader
信息: Start to monitor configuration file(s) at [config/queries]
5月 30, 2022 3:03:56 下午 ru.yandex.clickhouse.jdbcbridge.core.BaseRepository registerType
信息: Registering new type of NamedDataSource: [jdbc] -> [ru.yandex.clickhouse.jdbcbridge.impl.JdbcDataSource]
5月 30, 2022 3:03:56 下午 ru.yandex.clickhouse.jdbcbridge.core.BaseRepository registerType
信息: Default type of NamedDataSource is set to [jdbc]
5月 30, 2022 3:03:56 下午 ru.yandex.clickhouse.jdbcbridge.core.BaseRepository registerType
信息: Registering new type of NamedDataSource: [script] -> [ru.yandex.clickhouse.jdbcbridge.impl.ScriptDataSource]
5月 30, 2022 3:03:56 下午 ru.yandex.clickhouse.jdbcbridge.core.Utils loadJsonFromFile
信息: Loading JSON from file [config/httpd.json]...
5月 30, 2022 3:03:56 下午 ru.yandex.clickhouse.jdbcbridge.core.Utils loadJsonFromFile
警告: Failed to load JSON from file config/httpd.json
5月 30, 2022 3:03:56 下午 ru.yandex.clickhouse.jdbcbridge.JdbcBridgeVerticle startServer
信息: Starting web server...
5月 30, 2022 3:03:57 下午 ru.yandex.clickhouse.jdbcbridge.impl.JsonFileRepository reload
信息: No NamedSchema configuration found
5月 30, 2022 3:03:57 下午 ru.yandex.clickhouse.jdbcbridge.impl.JsonFileRepository reload
信息: No NamedQuery configuration found
5月 30, 2022 3:03:57 下午 ru.yandex.clickhouse.jdbcbridge.JdbcBridgeVerticle lambda$startServer$0
信息: Server http://0.0.0.0:9019 started in 30046 ms
5月 30, 2022 3:03:57 下午 ru.yandex.clickhouse.jdbcbridge.impl.JsonFileRepository reload
信息: Loading NamedDataSource configuration...
5月 30, 2022 3:03:57 下午 ru.yandex.clickhouse.jdbcbridge.core.BaseRepository update
信息: Adding NamedDataSource(id=myoracle)...
5月 30, 2022 3:04:08 下午 ru.yandex.clickhouse.jdbcbridge.internal.zaxxer.hikari.HikariDataSource <init>
信息: myoracle - Starting...
5月 30, 2022 3:04:08 下午 ru.yandex.clickhouse.jdbcbridge.internal.zaxxer.hikari.util.DriverDataSource <init>
警告: Registered driver with driverClassName=oracle.jdbc.driver.OracleDriver was not found, trying direct instantiation.
5月 30, 2022 3:04:11 下午 ru.yandex.clickhouse.jdbcbridge.internal.zaxxer.hikari.HikariDataSource <init>
信息: myoracle - Start completed.
出现最后一行 myoracle - Start completed. 表示成功
执行jps命令,查看结果
[root@t3-tkias-0025-app02 ~]# jps
8919 clickhouse-jdbc-bridge-2.0.7-shaded.jar
4728 Jps
第六步:配置Clickhouse
在Clickhouse的配置文件config.xml中,找到如下一段代码,移除注释,改成你的IP地址
<jdbc_bridge>
<host>XX.XX.XX.XX</host>
<port>9019</port>
</jdbc_bridge>
之后保存退出,用wget IP:9019 测试是否连通,显示能够connected就是成功了,否则请确保IP正确。
注意:Clickhouse-server需要重启才能使该配置生效。
第七步:测试
SELECT * FROM jdbc('myoracle', 'XXXXX', 'XXXXXXX');
参数2和3分别是Oracle里的模式和表。
我的CH是用Docker部署的,jdbc bridge部署在了容器的宿主机上,Oracle也是容器起的,测试了下速度,18万的表,从Oracle到CH抽取,用了2.4s,速度奇快。
另外,Oracle支持Null数据,CH不支持,所以CH建表的时候一定指定字段的默认值,抽取的时候遇到Null会自动填充为默认值,否则会报错。
至此,搞定。以后不管从HIve、mysql、pg还是别的数据库入库CH,都不需要什么工具了,下个JDBC,然后通过CH自带的jdbc()函数就能搞定,是不是很方便。