OpenLooKeng / Presto Connector原理

本文围绕OpenLooKeng Connector展开,介绍了其相关概念,包括SPI、PrestoPlugin和Connector。阐述了Connector结构,并详细说明了开发过程,涵盖Maven工程配置,针对非JDBC和JDBC数据源的开发方法,如非JDBC需手动实现组件,JDBC则基于规范适配操作逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OpenLooKeng Connector 扩展

一、什么是Connector

我们知道在整个Presto工程中所有的功能都是以插件的形式实现,而Connector则是一种负责Presto与数据源进行交互的插件,不同的数据库对应于不同的Connector。

SPI(Service Provider Interface)

SPI是JDK内置的服务提供/发现机制,它通过在ClassPath路径下的META-INF/services/目录中定义的文件,自动加载文件里所定义的类。该机制为很多框架的扩展提供了可能,如知名的JDBC就使用了该机制。

SPI特点:

  • SPI文件名为实现Service接口的全限定名
  • SPI文件内容为实现该接口的具体文件
  • 使用ServiceLoader.load(Class class)动态加载Service接口的实现类
  • 如果SPI实现的类在外部Jar包中,则需要将该jar包放在当前程序的classpath下
  • Service的实现类必须有无参构造方法

PrestoPlugin(插件)

OpenLookeng中有一个presto-spi模块,该模块即定义了OpenLooKeng对外暴露的SPI接口,实现对应的接口即可实现连接器类型函数系统访问控制等的功能。

特别的,OpenLooKeng的插件即实现了Plugin SPI的模块:

io.prestosql.spi.Plugin

通过在META-INF/services/io.prestosql.spi.Plugin文件中列出实现io.prestosql.spi.Plugin接口的具体类,即可使该实现通过java内置的ServiceLoader提供给OpenLooKeng。对于包含在OpenLooKeng源码中的插件,只要在pom.xml中包含<packaging>presto-plugin</packaging>就会自动创建spi文件。

Connector

Connector即连接器,是一类用于在OpenLookeng中提供查询特定数据源能力的插件。即使OpenLooKeng尚未支持当前数据源,只要将数据源与OpenLooKeng期望使用的API适配,创建一个Connector,即可扩展对该数据源的支持。

Connector实例由ConnectorFactory实例创建,OpenLooKeng调用插件上的getConnectorFactory()时会创建该ConnectorFactory实例。
ConnectorFactory可以返回一下实例:

  • ConnectorMetadata 元数据接口,允许OpenLooKeng查看模式列表、表列表、列列表等元数据信息。如果要接入的数据源是非关系型数据库,则需要将数据源映射到OpenLooKeng的 模式概念。
  • ConnectorSplitManager分片管理器,将表的数据分区为多块,将块由OpenLooKeng分发到不同的工作节点处理。对于没有已分区数据的数据源,比较好的策略是针对整张表返回单个分片。
  • ConnectorHandleResolver
  • ConnectorRecordSetProvider 记录集提供器,给定一个分片和一个列列表的情况下,记录集提供器将数据提供给OpenLooKeng执行引擎。记录集提供器创建一个RecordSet,RecordSet又相应的创建一个RecordCursor,OpenLooKeng使用该RecordCursor来读取每一行的值。

二、Connector 结构

在这里插入图片描述

三、Connector 开发

Maven工程配置

  1. 在OpenLooKeng源码根目录创建与Connector名对应的目录,并在该目录中创建pom.xml
  2. 将当前模块加入io.hetu.core组中,版本需要和当前OpenLooKeng工程版本一致:
<parent>
    <artifactId>presto-root</artifactId>
    <groupId>io.hetu.core</groupId>
    <version>316</version>
</parent>
  1. 定义当前工程信息,添加packaging选项为hetu-plugin在打包编译时会将当前工程打包到heto-coreplugin目录下。
<artifactId>hetu-example</artifactId>
<version>${dep.hetu.version}</version>
<description>Hetu - Example Connector</description>
<packaging>hetu-plugin</packaging>
  1. 引入SPI依赖,每个Plugin工程都会依赖presto-spi模块:
<dependency>
    <groupId>io.hetu.core</groupId>
    <artifactId>presto-spi</artifactId>
    <scope>provided</scope>
</dependency>
  1. 在整个编译整个OpenLooKeng工程时,我们需要将自定义添加的connector也编译打包到plugin目录下,通过以下的配置即可达到我们的目的:
  • 在hetu core根目录下的pom.xml中,将我们新增的Connector加入到modules中。
    <modules>
      ……
      <module>hetu-example</module>
      ……
    </modules>
    
  • 在hetu-server的src/main/provisio/hetu.xml配置文件中,注册新增的Connector。
    <artifactSet to="plugin/hetu-example">
      <artifact id="${project.groupId}:hetu-example:zip:${project.version}">
          <unpack />
      </artifact>
    </artifactSet>
    

经过以上步骤,新增Connector的准备工作就已经完成。在开发过程中根据具体实现使用到的类来添加依赖。Plugin使用了独立的类加载器,和其他的类是隔离的,因此Plugin可以使用不同版本的类库,区别于hetu core内部使用的版本。

Connector的加载由ConnectorFactory实现。但真正能够使用该Connector还需要加载Catalog,所谓Catalog就是Hetu的数据源类别,Hetu通过如下三级结构来定义数据表。
在这里插入图片描述

非JDBC数据源

对于非JDBC数据源,我们需要根据数据源的情况,手动实现一个完整Connector的几个必须组件。

接口名作用
ConnectorFactoryConnector工厂
ConnectorMetadata获取数据源元数据
ConnectorHandleResolver获取各种Handler
ConnectorSplitManager处理任务分片
ConnectorRecordSetProvider
ConnectorPageSourceProvider
读取数据
ConnectorPageSinkProvider写入数据

其调用逻辑如下图:
Connector 调用

  • Metadata

    实现io.prestosql.spi.connector.ConnectorMetadata接口,提供了对数据源元数据的管理,例如列举Schemas、Tables、Columns信息,创建表、删除表,创建视图、删除视图等一系列DDL操作。

  • SplitManager

    Split详细描述了一个数据分片的具体内容,每种数据源的Split都不尽相同,数据源中定义的Split即为Source Stage中调度的Split。Split的分片合理性直接决定了Hetu读取数据源数据的效率。如果一个Split分片涵盖的数据量过大,数据不均匀,则会拖慢整个SQL;若过小,则会造成大量的CPU资源都耗费在调度Split的操作上。

    Splits通过SplitManager获取,最终是通过接口io.prestosql.spi.connector.ConnectorSplitManager的实现类,也就是各个Connector的SplitManager获取Split,该接口包括了以下方法用于获取Split:

    ConnectorSplitSource getSplits();
    

    ConnectorSplitSource为一个Connector中具体表的Split集合,主要包含以下几个方法:

    //批量获取Splits列表,maxSize默认为1000,Split如何组织以及每调用一次该方法如何返回ConnectorSplitBatch都由各个Connector定义
    CompletableFuture<ConnectorSplitBatch> getNextBatch(ConnectorPartitionHandle partitionHandle, int maxSize);
    
    //Split列表是否获取完毕
    boolean isFinished();
    
  • RecordSetProvider

    获取到Source Split后,将其调度到具体的Worker节点上执行数据读取,数据读取过程需要依赖Split对应的Connector所提供的数据读取类,也就是RecordSetProvider。

    数据源的RecordSetProvider均需要实现io.prestosql.spi.connector.ConnectorRecordSetProvider接口,接口定义也很简单,提供了输入参数是Split、表和表的列信息及输出为RecordSet的方法。

    RecordSet getRecordSet(
          ConnectorTransactionHandle transaction,
          ConnectorSession session,
          ConnectorSplit split,
          ConnectorTableHandle table,
          List<? extends ColumnHandle> columns);
    

    其中,RecordSet为io.prestosql.spi.connector.RecordSet,其定义的方法有:

    List<Type> getColumnTypes();
    RecordCursor cursor();
    

    cursor方法返回的RecordCursor就是真正的读取数据类,其定义了Split的数据读取方法,针对每个Split都会创建一个RecordCursor实例.

JDBC 数据源

什么是JDBC

JDBC(Java Database Connectivity),即Java数据库编程接口,是Java语言访问数据库的一种规范,是一套API。

JDBC API主要位于JDK中的java.sql包之中(JavaEE扩展内容位于javax.sql包中),数据库的JDBC驱动即针对该数据库的JDBC API接口实现类,任意数据库厂商或者个人都可以根据JDBC规范实现自己的驱动。

通过使用JDBC,JAVA开发人员可以使用相同的代码查询几乎任意一种数据库,不必考虑数据库方言。

JDBC Connector 原理

JDBC API的定义可知,理论上我们可以通过相同的Java代码去查询任意提供了JDBC驱动的数据库。

所以我们可以基于JDBC规范在OpenLooKeng中实现一套统一的、适配OpenLookeng Connector的数据库操作逻辑,当我们在面对不同JDBC数据源时,只需要替换JDBC驱动即可以对该数据源进行操作。

JDBC Connector 开发

基于上述原理,OpenLooKeng提供了JDBC Connector的适配代码——JdbcPlugin,开发JDBC 数据源的Connector,最理想的状态只需要引入对应数据源的驱动即可。

具体实现为:使用需要的Jdbc驱动实例构建ConnectionFactory即可。

但是!

不同的数据源各自有各自的特殊情况,对于JDBC的支持和实现细节都可能会有些许差异,所以应对不同的数据源,我们需要在了解该数据源特性和JDBC驱动使用的基础上,对原始JDBC进行一些适配性微调。

这些适配性调整的实现也很简单,只需要我们继承JdbcPlugin中对应的类型实现自己的处理类型,重载需要调整的方法即可。

通常需要调整的类型主要有:

  • JdbcPlugin 插件入口
  • JdbcMetadata 元数据管理类
  • BaseJdbcClient 数据库交互类
  • QueryBuilder Query处理类
impala是一种高性能分析型数据库,它基于Hadoop生态系统,可以快速执行复杂的查询。它使用列式存储、编译器技术和并行查询执行来实现高性能。 druid是一个快速、实时的数据存储和分析引擎,它适用于大规模的实时数据处理和探索式分析。它支持实时数据摄取、查询和可视化,可用于数据仪表盘和实时报告等应用。 presto是一种开源的分布式SQL查询引擎,它可以快速查询多种数据源,包括Hadoop、MySQL等。它具有高度可伸缩性和灵活性,可用于快速进行复杂的数据分析和联机查询。 kylin是一种开源的分布式分析引擎,它可以快速处理大规模数据集。它支持多维分析和复杂的OLAP查询,并提供了数据立方体和预计算功能,用于加速查询速度。 clickhouse是一种列式数据库管理系统,专门用于高性能分析型应用。它支持实时查询和高并发访问,并具有低延迟和高容量的优势,适用于大规模的数据分析和数据仪表盘等应用。 greenplum是一种高性能的并行关系数据库管理系统,适用于大规模数据仓库和分析型应用。它具有高度可伸缩性、并行查询和优化的特性,用于高速查询和处理大规模数据。 总的来说,这些数据库和查询引擎都旨在提供高性能和灵活性,以满足大规模数据分析和查询的需求,但它们在技术架构、数据存储方式和查询优化等方面存在一些差异。选择适合特定需求的数据库和查询引擎取决于实际情况和使用场景。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值