前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Trino连接ClickHouse代码浅析

Trino连接ClickHouse代码浅析

作者头像
skyyws
发布2022-05-20 08:50:54
9670
发布2022-05-20 08:50:54
举报
文章被收录于专栏:skyyws的技术专栏

最近在调研Trino和Clickhouse的打通问题,简单研究了下Trino对于CH的适配,这里简单总结下。详细的代码提交参见这个commit:Add ClickHouse Connector

加载Plugin

Trino在启动的时候,会加载所有已经支持的plugin,也就是说常说的connector,加载的路径位于plugin/下,如下所示:

1
1

可以看到,目前支持的plugin种类非常多,有40多个。这里以CH为例,加载完成之后,服务端会打印相应的日志:

代码语言:javascript
复制
2022-02-08T16:57:26.445+0800	INFO	main	io.trino.server.PluginManager	-- Loading plugin /data/impala/presto/data/plugin/clickhouse --
2022-02-08T16:57:26.463+0800	INFO	main	io.trino.server.PluginManager	Installing io.trino.plugin.clickhouse.ClickHousePlugin
2022-02-08T17:37:26.845+0800    INFO    main    io.trino.server.PluginManager   Registering connector clickhouse
2022-02-08T16:57:26.472+0800    INFO    main    io.trino.server.PluginManager   -- Finished loading plugin /data/impala/presto/data/plugin/clickhouse --

可以看到,这里主要就是加载了ClickHousePlugin这个类,相关的函数调用栈如下所示:

代码语言:javascript
复制
doStart(Server.java):126
-loadPlugins(PluginManager.java):129
--loadPlugins(ServerPluginsProvider.java):58
---loadPlugin(PluginManager.java):148
---loadPlugin(PluginManager.java):162
----installPlugin(PluginManager.java):168
-----installPluginInternal(PluginManager.java):191
------addConnectorFactory(ConnectorManager.java)

在服务启动之后,会先注册相应的ConnectorFactory,这里涉及到了比较多的类,我们将相关类的UML图简单整理了下:

plugin
plugin

ConnectorFactory里面就包含对应的plugin,对于CH而言,ClickHousePlugin。Plugin本身又包含了对应的ConnectionFactory。最终,对于CH的plugin来说,就是使用了ClickHouseDriver去连接CH集群的。后续再进行各种元数据加载和查询的时候,就会利用这个connection来与CH集群进行交互,如下所示:

2
2

加载ClickHouse元数据

下面简单来看下Trino是如何加载catalog的。简单的代码调用栈如下所示:

代码语言:javascript
复制
doStart(Server.java):128
-loadCatalogs(StaticCatalogStore.java):68
--loadCatalog(StaticCatalogStore.java)

默认配置在服务端路径的etc/catalog/下,以“.properties”结尾的所有文件,如下所示:

3
3

通过循环加载每个catalog对应的配置文件,如下所示:

代码语言:javascript
复制
for (File file : listFiles(catalogConfigurationDir)) {
    if (file.isFile() && file.getName().endsWith(".properties")) {
        loadCatalog(file);
    }
}

private File catalogConfigurationDir = new File("etc/catalog/");

这里同样以ClickHouse为例,常见的配置如下:

代码语言:javascript
复制
connector.name=clickhouse
connection-url=jdbc:clickhouse://host:8123/
connection-user=xxx
connection-password=xxx
allow-drop-table=true
case-insensitive-name-matching=true

当服务启动之后,同样会打印相关的日志,如下所示:

代码语言:javascript
复制
2022-02-08T16:13:31.644+0800    INFO    main    io.trino.metadata.StaticCatalogStore    -- Loading catalog etc/catalog/clickhouse.properties --
2022-02-08T16:13:32.098+0800    WARN    main    ru.yandex.clickhouse.ClickHouseDriver   ******************************************************************************************
2022-02-08T16:13:32.098+0800    WARN    main    ru.yandex.clickhouse.ClickHouseDriver   * This driver is DEPRECATED. Please use [com.clickhouse.jdbc.ClickHouseDriver] instead.  *
2022-02-08T16:13:32.098+0800    WARN    main    ru.yandex.clickhouse.ClickHouseDriver   * Also everything in package [ru.yandex.clickhouse] will be removed starting from 0.4.0. *
2022-02-08T16:13:32.098+0800    WARN    main    ru.yandex.clickhouse.ClickHouseDriver   ******************************************************************************************
2022-02-08T16:13:32.270+0800    INFO    main    io.trino.metadata.StaticCatalogStore    -- Added catalog clickhouse using connector clickhouse --

根据上面的Plugin加载流程可以知道,Trino会根据这些配置项利用ClickHouseDriver来构造CH的Connection,进而进行各种操作。 例如,当我们通过show tables查看CH集群指定db下的表时,就会通过ClickHouseClient中的方法来执行,相关代码如下所示:

代码语言:javascript
复制
public ResultSet getTables(Connection connection, Optional<String> schemaName, Optional<String>   
    tableName) throws SQLException
{
  // ClickHouse maps their "database" to SQL catalogs and does not have schemas
  DatabaseMetaData metadata = connection.getMetaData();
  return metadata.getTables(null,schemaName.orElse(null),
      escapeNamePattern(tableName, metadata.getSearchStringEscape()).orElse(null),
      new String[] {"TABLE", "VIEW"});
}

相关的类图如下所示:

jdbc
jdbc

这里CH对应的就是ClickHouseClient。

查询ClickHouse数据

当执行查询的时候,也是通过CH的jdbc来执行的,首先会通过ClickHouseClient来构造一个PreparedStatement,相关的调用栈如下所示:

代码语言:javascript
复制
buildSql(BaseJdbcClient.java):380
-prepareStatement(QueryBuilder.java):185
--getPreparedStatement(BaseJdbcClient.java):763  --实际当前是ClickHouseClient类型
---prepareStatement(ForwardingConnection.java):54
----prepareStatement(ClickHouseConnectionImpl.java)

后续就会通过PreparedStatement.executeQuery()来执行真正的查询,所以,对于CH的查询来说,Trino还是通过JDBC来让CH自己去查询。关于整个查询流程的代码,后续有空再深入研究。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 加载Plugin
  • 加载ClickHouse元数据
  • 查询ClickHouse数据
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档