• Trino 插件的开发和部署
  • 发布于 2个月前
  • 392 热度
    0 评论
前言
根据官网描述,Trino 是一个快速的、分布式的大数据查询引擎,支持单数据源查询及多数据源的联邦查询,且内置支持多种数据源,如 Hive、MySQL、Kafka、Clickhouse、Elasticsearch 等。Trino 基于 Java SPI 提供了一套优秀的插件体系,并开放了非常丰富的扩展点,供用户开发自定义插件以满足特定需求,如审计日志、权限控制等。

插件介绍
Trino 的插件是基于 Java 标准 SPI 机制实现,插件类配置在 META-INF/services 目录中,通过 Java ServiceLoader 加载。Java 的 SPI 机制在此不赘述。
Trino 定义了一个统一的插件接口类 Plugin,不同的插件都需要实现该类。Plugin 接口提供了获取各类插件的入口方法。其代码结构如下:
public interface Plugin
{
    default Iterable<ConnectorFactory> getConnectorFactories()
    {
        return emptyList();
    }
    default Iterable<SystemAccessControlFactory> getSystemAccessControlFactories()
    {
        return emptyList();
    }
    default Iterable<EventListenerFactory> getEventListenerFactories()
    {
        return emptyList();
    }
    // 堆代码 duidaima.com
    // 更多插件创建方法详见源码 ... ...
}
如 getEventListenerFactories() 方法提供了获取事件监听插件的入口方法,其提供了 EventListenerFactory 工厂类,当需要创建插件实例时,Trino 调用该工厂类创建。其他类型的插件同理。

Plugin 接口中的每一个方法会提供一个默认实现,默认实现返回一个空集合,此时不会创建插件实例。当我们需要开发一个新 Trino 插件时,按需实现 Plugin 接口中的方法。比如,需要自定义的事件插件时,则实现 getEventListenerFactories() 方法。

Trino 提供了多种插件来满足不同的场景,最常见的如 connector 插件,通过 connector 插件,我们可以开发一个自定义的数据源连接器。其他常用插件如:
1. SystemAccessControl 权限控制
2. EventListener 事件监听
3. Functions 自定义函数
4. PasswordAuthenticator 密码验证

更多插件参见官网,这里不一一列举。

插件开发
下面以权限控制插件为例,来说明开发 Trino 自定义插件的过程,开发过程使用 maven 打包。

依赖配置
在插件项目中的 maven pom.xml 文件中加上 Trino 插件的依赖:
<dependency>
    <groupId>io.trino</groupId>
    <artifactId>trino-spi</artifactId>
    <scope>provided</scope>
</dependency>
注:依赖的 scope 为 provided。Trino 在运行时会提供该包的类,所以不需要打包到插件包中。另外 Trino 也提供了 Jackson 和 Slice 依赖包,这些包需要使用 Trino 提供的版本。开发过程中需要的其他依赖,则需要加入到插件中,Trino 使用单独的类加载器来隔离不同的插件类加载。

代码开发
1、自定义一个 Java 类来实现 Plugin 接口,由于是权限控制插件,需要实现接口中的 getSystemAccessControlFactories() 方法,该方法返回一个 SystemAccessControlFactory 集合。
public class CustomAccessControlPlugin implements Plugin {
    @Override
    public Iterable<SystemAccessControlFactory> getSystemAccessControlFactories() {
        return ImmutableList.of(new CustomAccessControlFactory());
    }
}
2、SystemAccessControlFactory 是 Trino 用来创建权限控制插件的工厂类,所以我们继续定义一个类来实现 SystemAccessControlFactory 接口。
public class CustomAccessControlFactory implements SystemAccessControlFactory {
    @Override
    public String getName() {
        return "my-custom-access-control";
    }

    @Override
    public SystemAccessControl create(Map<String, String> config) {
        return new CustomTableAccessControl(config);
    }
}
该类需要实现两个方法:
getName() 返回插件名称,必须唯一。
create() 返回自定义的权限控制类 SystemAccessControl。其传参 Map<String, String> config 中的值以 KeyValue 形式配置在权限配置文件中。

3、SystemAccessControl 权限控制类提供具体的权限控制功能,包含并不限于以下能力:
.校验用户是否可以执行查询等操作。
.校验用户是否可以对 catalog、schema、table 做访问、DML、DDL 操作。
.支持数据行过滤、列掩码等功能。
.验证用户是否可以读写系统属性等等。
public interface SystemAccessControl
{
    default void checkCanSelectFromColumns(SystemSecurityContext context, CatalogSchemaTableName table, Set<String> columns)
    {
        denySelectColumns(table.toString(), columns);
    }
    default List<ViewExpression> getRowFilters(SystemSecurityContext context, CatalogSchemaTableName tableName)
    {
        return List.of();
    }
    default List<ViewExpression> getColumnMasks(SystemSecurityContext context, CatalogSchemaTableName tableName, String columnName, Type type)
    {
        return List.of();
    }
    // 更多权限控制方法详见源码 ... ...
}
代码示例中我们例举了几个权限控制方法:
checkCanSelectFromColumns,校验用户是否可以从某张表中查询某些字段,从方法参数可以看到,Trino 调用插件方法时传入了 table 和 columns 参数,table 的类型是 CatalogSchemaTableName,CatalogSchemaTableName 中包含了 catalogName、schemaName、tableName 信息。SystemSecurityContext context 中携带了上下文信息,包含本次查询的 queryId,以及用户信息:user、principal、groups 等。根据这些信息,我们可以结合权限控制需求,开发定制化的权限控制逻辑。

getRowFilters,对表做行级权限控制,返回一个 ViewExpression 集合,ViewExpression 中的 expression 字段为 SQL 过滤条件。
getColumnMasks,给字段加掩码,实际使用时,可以根据需求对该字段做加密、脱敏等处理。

插件更多的权限控制方法,可以参见 Trino 源码,这里不再延伸。

部署配置
部署
首先使用 maven 打包命令,打包一个插件 jar 包。
然后,在 Trino 安装路径下,找到 plugin 目录。Trino 的插件就放在这个目录中。在 plugin 目录下创建一个子目录 my-custom-access-control,名称和插件名称保持一致。在新建的目录中放入打包好的插件 jar 包,其他依赖包一并放入。虽然官网说明表示插件必须部署到 Trino 集群的所有节点中(coordinator 和 workers),但实际部分插件只部署到 coordinator 节点也可以,所以实际可按需部署。

配置
插件部署后,还需要在 Trino 集群的节点添加插件配置文件才会生效。Trino 配置文件放在安装目录下的 etc 目录中。以权限控制插件为例,默认的插件配置文件名称为 access-control.properties,在 etc 目录中创建 access-control.properties 文件。编辑文件,添加如下配置:
access-control.name = my-custom-access-control
custom-property1 = custom-value1
custom-property2 = custom-value2
Trino 会根据 access-control.name 配置的值查找插件,所以需要和 SystemAccessControlFactory.getName() 方法的返回值保持一致。除了 access-control.name 之外的自定义配置都会通过 Map<String, String> config 传入到 SystemAccessControlFactory.create() 方法中,以供在插件中使用。

Trino 支持配置多个权限控制插件,可以在 etc/config.properties 文件中,添加 access-control.config-files 指定多个配置文件,如下:
access-control.config-files = etc/access-control-1.properties, etc/access-control-2.properties

总结
综上所述,我们已经完成了 Trino 插件的开发和部署,启动 Trino 后,可以在控制台查看日志确定插件是否已经安装成功。
用户评论