Trino连接ClickHouse代码浅析

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

加载Plugin

Trino在启动的时候,会加载所有已经支持的plugin,也就是说常说的connector,加载的路径位于plugin/下,如下所示:
1
可以看到,目前支持的plugin种类非常多,有40多个。这里以CH为例,加载完成之后,服务端会打印相应的日志:

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这个类,相关的函数调用栈如下所示:

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

加载ClickHouse元数据

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

doStart(Server.java):128
-loadCatalogs(StaticCatalogStore.java):68
--loadCatalog(StaticCatalogStore.java)

默认配置在服务端路径的etc/catalog/下,以“.properties”结尾的所有文件,如下所示:
3
通过循环加载每个catalog对应的配置文件,如下所示:

for (File file : listFiles(catalogConfigurationDir)) {
    if (file.isFile() && file.getName().endsWith(".properties")) {
        loadCatalog(file);
    }
}

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

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

connector.name=clickhouse
connection-url=jdbc:clickhouse://host:8123/
connection-user=xxx
connection-password=xxx
allow-drop-table=true
case-insensitive-name-matching=true

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

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中的方法来执行,相关代码如下所示:

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
这里CH对应的就是ClickHouseClient。

查询ClickHouse数据

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

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自己去查询。关于整个查询流程的代码,后续有空再深入研究。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值