Trino 插件開發入門

前言

根據官網描述,Trino 是一個快速的、分佈式的大數據查詢引擎,支持單數據源查詢及多數據源的聯邦查詢,且內置支持多種數據源,如 HiveMySQLKafkaClickhouseElasticsearch 等。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();
    }

    // 更多插件創建方法詳見源碼 ... ...
}

如 getEventListenerFactories() 方法提供了獲取事件監聽插件的入口方法,其提供了 EventListenerFactory 工廠類,當需要創建插件實例時,Trino 調用該工廠類創建。其他類型的插件同理。

Plugin 接口中的每一個方法會提供一個默認實現,默認實現返回一個空集合,此時不會創建插件實例。當我們需要開發一個新 Trino 插件時,按需實現 Plugin 接口中的方法。比如,需要自定義的事件插件時,則實現 getEventListenerFactories() 方法。

Trino 提供了多種插件來滿足不同的場景,最常見的如 connector 插件,通過 connector 插件,我們可以開發一個自定義的數據源連接器。其他常用插件如:

更多插件參見官網,這裏不一一列舉。

插件開發

下面以權限控制插件爲例,來說明開發 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);
    }
}

該類需要實現兩個方法:

3、SystemAccessControl 權限控制類提供具體的權限控制功能,包含並不限於以下能力:

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();
    }

    // 更多權限控制方法詳見源碼 ... ...
}

代碼示例中我們例舉了幾個權限控制方法:

插件更多的權限控制方法,可以參見 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 後,可以在控制檯查看日誌確定插件是否已經安裝成功。

參考

Trino 官方文檔(https://trino.io/docs/current/)

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/n5-CkF8rYRjqGWMEh1PvkQ