交互式分析的诉求
在 OSS Tables 的生态里,Trino 是分析快刀,只读不写,分析师写一条 SQL 就能秒级查湖里的数据,不需要提 Spark 作业也不用跑 Flink 任务。数据通过 Spark、Flink 或 Kafka Connect 写进了 OSS Tables,下一个问题就是:谁来查?
BI 分析师不会写 Spark 作业,数据科学家也不想为了一次即席查询去提交一个 Flink 任务,但他们需要的东西很简单:打开 SQL 客户端,写一条 SELECT,几秒内拿到结果。Trino(原 PrestoSQL)就是干这个的,它是一个分布式 SQL 查询引擎,以低延迟交互式查询为主,也能通过容错执行承担批式作业,本文聚焦即席查询场景,专注于交互式查询。对接数据湖是 Trino 最典型的用法场景。
但 Trino 查 OSS Tables 有一个现实问题:OSS Tables 返回的数据路径使用 oss:// 前缀,而 Trino 的原生 S3 文件系统只认 s3://、s3a://、s3n:// 三种协议,且 Trino 社区目前还没有原生支持 oss://,所以需要对源码做少量修改来注册这个协议。当然,改动很小,只涉及两个模块,做完之后,Trino 就能像查 S3 上的 Iceberg 表一样,直接查 OSS Tables。
OSS Tables 兼容 Apache Iceberg REST Catalog 协议。可以通过 Trino 的原生 S3 文件系统(fs.native-s3)对接 OSS Tables,使用标准 SQL 查询和写入 Table Bucket 中的数据。该方式需要对 Trino 源码进行少量修改以支持 oss:// 协议,适合对编译环境有掌控的场景。
重要 由于 Trino 社区尚未原生支持 oss:// 文件系统协议,如需使用 Trino 访问 OSS Tables,需要修改 Trino 源码并重新编译两个模块,生成 jar 包后在 Trino 环境中替换并重启。
步骤一:修改Trino源码
OSS Tables 返回的数据路径使用 oss:// 前缀,而 Trino 原生 S3 文件系统仅识别 s3://、s3a://、s3n:// 协议。需要在以下两个模块中注册 oss 协议。
修改 trino-filesystem-s3
找到 S3 Location 校验逻辑,将 oss 添加到允许的 scheme 集合中:
// 修改前 checkArgument(Set.of("s3", "s3a", "s3n").contains(location.scheme().get()), "Wrong scheme for S3 location: %s", location); // 修改后 checkArgument(Set.of("s3", "s3a", "s3n", "oss").contains(location.scheme().get()), "Wrong scheme for S3 location: %s", location);
修改 trino-filesystem-manager
在文件系统工厂绑定处添加 oss scheme 的映射:
factories.addBinding("s3").to(Key.get(TrinoFileSystemFactory.class, FileSystemS3.class)); factories.addBinding("s3a").to(Key.get(TrinoFileSystemFactory.class, FileSystemS3.class)); factories.addBinding("s3n").to(Key.get(TrinoFileSystemFactory.class, FileSystemS3.class)); // 在已有的 s3/s3a/s3n 绑定后添加: factories.addBinding("oss").to(Key.get(TrinoFileSystemFactory.class, FileSystemS3.class));
编译并替换
编译上述两个模块后,将生成的 JAR 包替换 Trino 部署目录中对应的原始 JAR,然后重启 Trino 服务。
# 编译 trino-filesystem-s3 mvn -pl lib/trino-filesystem-s3 -am package -DskipTests # 编译 trino-filesystem-manager mvn -pl lib/trino-filesystem-manager -am package -DskipTests # 替换 JAR(以 Trino 安装目录 /opt/trino 为例) cp lib/trino-filesystem-s3/target/trino-filesystem-s3-*.jar /opt/trino/lib/ cp lib/trino-filesystem-manager/target/trino-filesystem-manager-*.jar /opt/trino/lib/
步骤二:创建Table Bucket
在开始写入数据之前,需要创建 Table Bucket 和 Namespace。可以使用 ossutil 或 AWS CLI 创建。
方式一:使用ossutil
1. 安装或升级 ossutil
请安装ossutil 2.3.0以上版本,如已安装 ossutil,可执行以下命令升级到最新版本:
ossutil update -f
2. 配置凭证
执行 ossutil config 命令,按提示输入 AccessKey ID、AccessKey Secret 和 Region。
3. 创建 Table Bucket
ossutil tables-api create-table-bucket --name {table bucket名称} --endpoint http://{endpint} --region {region}
命令执行成功后,返回结果中包含 Table Bucket ARN,请记录该值。
4. 创建 Namespace
ossutil tables-api create-namespace --table-bucket-arn {Table Bucket ARN} --namespace {Namespace名称} --endpoint http://{endpint}
重要:Namespace 和 Table 名称不能包含连字符(-),可使用下划线(_),这是因为名称会用于 SQL 语句中的标识符。
5. 创建 Table
您可以选择以下任一方式创建 Iceberg 表:
- 通过其他计算引擎创建(如 Spark)。
- 通过 ossutil 创建:先将表 schema 保存为 JSON 文件,再调用
create-table。
以下示例的 schema 文件 schema.json 定义了 3 个字段:
{ "iceberg": { "schema": { "fields": [ {"name": "event_id", "type": "string", "required": true}, {"name": "event_time", "type": "string"}, {"name": "event_type", "type": "string"} ] } } }
基于 schema 文件创建 Table:
ossutil tables-api create-table --table-bucket-arn {bucketArn} --namespace {namespace名称} --name {表名称} --format ICEBERG --metadata file://{文件路径} --endpoint --endpoint http://{endpint}
方式二:使用AWS CLI
OSS Tables 兼容 S3 Tables API,也可以使用 AWS CLI 管理 Table Bucket。
1. 安装 AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip sudo ./aws/install
2. 配置凭证
执行 aws configure 命令,按提示输入 AccessKey ID、AccessKey Secret 和 Region。
3. 创建 Table Bucket
aws s3tables --endpoint http://{endpint} create-table-bucket --region {region} --name {table bucket名称}
命令执行成功后,返回结果中包含 Table Bucket ARN。
4. 创建 Namespace
aws s3tables --endpoint http://{endpoint} create-namespace --table-bucket-arn {Table Bucket ARN} --namespace {namespace名称}
5. 创建 Table
- 通过其他计算引擎(如 Spark)创建表
- 使用 AWS CLI 创建。使用 AWS CLI 时,先将完整的入参保存为 JSON 文件
create-table.json,再调用create-table。
{ "tableBucketARN": "{BucketArn}", "namespace": "{namespace名称}", "name": "{表明}", "format": "ICEBERG", "metadata": { "iceberg": { "schema": { "fields": [ {"name": "event_id", "type": "string","required": true}, {"name": "event_time", "type": "string"}, {"name": "event_type", "type": "string"} ] } } } }
aws s3tables --endpoint http://{endpoint} create-table --cli-input-json file://{文件路径}
6. 管理后台维护任务
OSS Tables 支持自动执行 Iceberg 表的后台维护(如文件清理、文件合并等),通过 AWS CLI 可以查询和配置维护任务。
查询 Table 维护任务状态:
aws s3tables get-table-maintenance-job-status \ --table-bucket-arn="{bucketArn}" \ --namespace="{namespace名称}" \ --name="{表名}"
配置 Bucket 级维护策略(文件清理):
aws s3tables put-table-bucket-maintenance-configuration \ --table-bucket-arn {tableArn} \ --type icebergUnreferencedFileRemoval \ --value '{"status":"enabled","settings":{"icebergUnreferencedFileRemoval":{"unreferencedDays":4,"nonCurrentDays":10}}}'
配置 Table 级维护策略(小文件合并):
aws s3tables put-table-maintenance-configuration \ --table-bucket-arn {bucketArn} \ --type icebergCompaction \ --namespace {namespace名称} \ --name {表名} \
步骤三:配置Trino Catalog
OSS Tables 提供 Iceberg REST Catalog 端点,Trino 通过 Iceberg Connector 的 REST Catalog 模式连接。Endpoint格式如下:
- 内网:
https://{region}-internal.oss-tables.aliyuncs.com/iceberg - 外网:
https://{region}.oss-tables.aliyuncs.com/iceberg
OSS Tables 提供S3FileIO访问OSS数据面使用的访问端点,Spark 通过该端点访问表数据。Endpoint格式如下:
创建 Catalog 配置文件
在 Trino 的 etc/catalog/ 目录下创建配置文件(例如 oss_tables.properties):
connector.name=iceberg iceberg.catalog.type=rest iceberg.rest-catalog.uri=https://{region}-internal.oss-tables.aliyuncs.com/iceberg iceberg.rest-catalog.warehouse=<Table Bucket ARN> iceberg.rest-catalog.security=SIGV4 iceberg.rest-catalog.signing-name=osstables iceberg.rest-catalog.view-endpoints-enabled=false fs.hadoop.enabled=false fs.native-s3.enabled=true s3.endpoint=https://oss-{region}-internal.aliyuncs.com s3.region=<Region> s3.aws-access-key=<AccessKey ID> s3.aws-secret-key=<AccessKey Secret> s3.path-style-access=true
配置参数说明
参数 |
是否必填 |
说明 |
|
是 |
固定为 |
|
是 |
固定为 |
|
是 |
REST Catalog 端点 URL。格式: |
|
是 |
Table Bucket ARN。格式: |
|
是 |
固定为 |
|
是 |
固定为 |
|
是 |
固定为 |
|
是 |
固定为 |
|
是 |
OSS 数据面端点。格式: |
|
是 |
固定为 |
步骤四:使用SQL操作数据
配置完成并重启 Trino 后,您可以使用 Trino CLI 或 JDBC 客户端连接,通过标准 SQL 操作 OSS Tables 中的数据。
建表示例
CREATE TABLE ${catalog}.${namespace}.orders ( order_id BIGINT, customer VARCHAR, amount DECIMAL(10,2), order_date DATE, created_at TIMESTAMP(6) ) WITH ( format = 'PARQUET', partitioning = ARRAY['day(order_date)'], );
查询示例
SELECT * FROM ${catalog}.${namespace}.orders limit 10;
权限配置
使用 RAM 用户或 STS 临时凭证访问 OSS Tables 时,需确保对应身份具备所需的操作权限。
资源定义
- Table Bucket ARN:
acs:osstables:<Region>:<阿里云账号ID>:bucket/<bucket_name> - Table ARN:
acs:osstables:<Region>:<阿里云账号ID>:bucket/<bucket_name>/table/<table_id>
Action 定义
下表列出 OSS Tables 支持的 Action,及其是否支持跨账号授权:
分类 |
Action |
跨账号访问 |
Table Bucket 级别 |
|
不允许 |
|
允许 |
|
|
不允许 |
|
|
允许 |
|
|
允许 |
|
|
允许 |
|
|
允许 |
|
|
允许 |
|
|
不允许 |
|
|
不允许 |
|
|
不允许 |
|
|
允许 |
|
|
允许 |
|
|
不允许 |
|
|
不允许 |
|
|
不允许 |
|
Table 级别 |
|
允许 |
|
允许 |
|
|
不允许 |
|
|
不允许 |
|
|
不允许 |
|
|
允许 |
|
|
允许 |
|
|
允许 |
|
|
允许 |
|
|
允许 |
|
|
允许 |
|
|
允许 |
|
|
允许 |
|
|
不允许 |
|
|
不允许 |
|
|
允许 |
Iceberg REST操作与权限映射
下表列出 Iceberg REST Catalog 各操作所需的 OSS Action:
Iceberg REST 操作 |
所需 OSS Action |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|