Clickhouse 通过JDBC方式从Oracle抽取数据,不借助任何抽数工具。顺便聊下Airbyte

最近遇到实际项目中从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

https://github.com/ClickHouse/clickhouse-jdbc-bridge/releases/download/v2.0.7/clickhouse-jdbc-bridge-2.0.7-shaded.jar

把上面地址直接粘贴到浏览器下载。

第二步:下载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/nvBP9icon-default.png?t=N176http://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()函数就能搞定,是不是很方便。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用JDBC来批量插入数据ClickHouse数据库。下面是一个简单的示例代码来演示如何使用JDBC批量插入数据: ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class ClickHouseBatchInsert { public static void main(String[] args) { // JDBC连接信息 String url = "jdbc:clickhouse://localhost:8123/default"; String username = "your_username"; String password = "your_password"; // SQL插入语句 String sql = "INSERT INTO your_table (column1, column2, column3) VALUES (?, ?, ?)"; // 数据集 Object[][] data = { {"value1_1", "value1_2", "value1_3"}, {"value2_1", "value2_2", "value2_3"}, {"value3_1", "value3_2", "value3_3"} }; try (Connection conn = DriverManager.getConnection(url, username, password); PreparedStatement pstmt = conn.prepareStatement(sql)) { // 关闭自动提交 conn.setAutoCommit(false); // 批量插入数据 for (Object[] row : data) { for (int i = 0; i < row.length; i++) { pstmt.setObject(i + 1, row[i]); } pstmt.addBatch(); } // 执行批量插入 int[] result = pstmt.executeBatch(); // 提交事务 conn.commit(); System.out.println("成功插入 " + result.length + " 条数据"); } catch (SQLException e) { e.printStackTrace(); } } } ``` 在这个示例中,你需要将`url`、`username`和`password`替换为你实际的ClickHouse连接信息,将`your_table`替换为你要插入数据的目标表名。然后,根据你的数据集,调整`data`数组中的值和列数。 这个示例中使用了`PreparedStatement`来执行预编译的SQL语句,并使用`addBatch()`方法将批量插入的每一行添加到批处理中。最后,通过调用`executeBatch()`方法执行批处理操作,并使用`commit()`方法提交事务。 这样,你就可以使用JDBC批量插入数据ClickHouse数据库了。希望对你有所帮助!如果有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值