目录
- 问题背景:湖仓查询为什么要把存储和引擎解耦
- RustFS 在湖仓里的位置:S3 兼容的数据文件底座
- 一键拉起:rustfs + polaris + trino 的 docker-compose
- 跑通直查:Iceberg catalog 配置与 SQL 验证
- 边界与取舍:path-style 必需、与 DuckDB 单机的区别、生产注意
- 总结与下一步
1. 问题背景:湖仓查询为什么要把存储和引擎解耦
一套湖仓起来之后,最常见的痛点不是"算不了",而是"数据在两块地方、权限两套、扩容各扩各的"。我给一个做用户行为分析的团队搭查询层时,他们原本把 Parquet 直接堆在本地 NFS 上,Spark 一并发查询就把 NFS 打满,扩容量还受单机文件系统限制。后来那个团队把存储换成 S3 兼容对象存储、计算交给 Trino,读写路径和扩缩容就彻底分开了——存储按对象数扩,计算按查询并发扩。
关键前提是对象存储得"够标准":Iceberg 的元数据文件、manifest、data file 全走 S3 接口,catalog 通过 REST 协议管表结构,数据文件落到对象存储。如果存储对 S3 的兼容有偏差,List、multipart、path-style 这些细节就会在查询时咬人。RustFS 因为是 100% S3 兼容,又能私有化部署,正好适合当这个底座。Apache Polaris 的官方 Trino 指南甚至直接用它作示例存储后端,下面我照那份指南把链路跑通。
2. RustFS 在湖仓里的位置:S3 兼容的数据文件底座
在 Iceberg 的架构里,RustFS 不碰表结构,只负责兜住数据文件。分工是这样:Trino 是 SQL 查询引擎,Polaris 是 Iceberg REST Catalog(管 namespace、table、schema),RustFS 提供 S3 兼容接口存 Iceberg 的 metadata 和 data file。三者通过标准协议对接,彼此不绑死实现。
为什么 RustFS 适合干这个活:一是 S3 100% 兼容,Iceberg 的s3://路径访问、multipart 上传、path-style 寻址都能直接用,不用改连接器;二是可以私有化部署在自有机房或任意云,数据不出域,适合合规和成本敏感的场景;三是和 Trino/Spark/PyIceberg 这些 Iceberg REST 客户端共用同一套接入方式,换引擎不用换存储。对 AI 训练场景也顺——特征表、样本清单以 Iceberg 落 RustFS,训练作业和查询作业共用一块存储。
3. 一键拉起:rustfs + polaris + trino 的 docker-compose
Apache Polaris 的指南给了现成的 docker-compose:一个rustfs服务当 S3 存储,一个polaris跑 REST Catalog(示例用内存 metastore),一个polaris-setup引导出 catalog/grant/namespace,一个trino带着 Iceberg connector 指向 Polaris。起之前设好端点变量:
exportS3_ENDPOINT=http://rustfs:9000dockercompose-fsite/content/guides/rustfs/docker-compose.yml\-fsite/content/guides/trino/docker-compose.yml updockerexec-it$(dockerps-q--filtername=trino)trino这里有一点值得点出来:RustFS 在 compose 里就是个普通 S3 服务,Polaris 写 Iceberg 元数据时用内部地址http://rustfs:9000(endpointInternal),外部客户端用http://localhost:9000。存储和 catalog 解耦之后,端点内外分流是标准做法,不影响数据落点。
4. 跑通直查:Iceberg catalog 配置与 SQL 验证
Trino 侧真正要配的是 Iceberg catalog 的属性文件catalog/polaris.properties,核心是把 S3 端点指到 RustFS,并打开 path-style 访问。下面这张表是照 Polaris 指南整理的必填项:
connector.name=iceberg iceberg.catalog.type=rest iceberg.rest-catalog.uri=http://polaris:8181/api/catalog iceberg.rest-catalog.warehouse=quickstart_catalog iceberg.rest-catalog.security=OAUTH2 iceberg.rest-catalog.vended-credentials-enabled=true fs.s3.enabled=true s3.endpoint=http://rustfs:9000 # 指向 RustFS 的 S3 兼容端点(默认 9000) s3.path-style-access=true # RustFS 必需,否则 Iceberg 数据文件寻址失败polaris-setup已经建好了quickstart_catalog,连上 Trino CLI 直接建表写数:
CREATESCHEMApolaris.demo;USEpolaris.demo;CREATETABLEevents(event_idBIGINT,event_typeVARCHAR,user_idBIGINT,created_atTIMESTAMP(6)WITHTIMEZONE);INSERTINTOeventsVALUES(1,'page_view',101,TIMESTAMP'2024-10-01 10:00:00 UTC'),(2,'click',102,TIMESTAMP'2024-10-01 11:30:00 UTC'),(3,'purchase',101,TIMESTAMP'2024-10-02 09:15:00 UTC');SELECTevent_type,count(*)AScntFROMeventsGROUPBYevent_typeORDERBYcntDESC;跑通这条 SELECT,说明数据文件已经落到 RustFS、元数据在 Polaris、查询路径全通。RustFS 控制台(默认http://localhost:9001)里能看到对应的 bucket 和对象增长。
5. 边界与取舍:path-style 必需、与 DuckDB 单机的区别、生产注意
几个落地时容易踩、但说清就不慌的点:
s3.path-style-access=true是 RustFS 必需项。RustFS 走 path-style 寻址,Iceberg 的s3://bucket/key要靠它解析,漏了这项查询会找不到数据文件。这是接入边界,不是 bug。- Trino 官方只测了 AWS S3 与 MinIO 的 S3 兼容。文档原话是其他存储系统需自行测试并咨询厂商;RustFS 出现在 Polaris 官方指南里,等于这份组合已经被指南作者验证过一轮,但真上生产仍建议用自己的表结构和数据量再扫一遍。
- 和 DuckDB 单机的区别:DuckDB 适合分析师在笔记本上直接
SELECTRustFS 上的 Parquet/Iceberg,轻量、无需服务;Trino 是分布式 SQL 引擎,适合多并发、跨大表的湖仓查询,代价是要起 Polaris + Trino 一组服务。选型看查询规模和并发,不是谁替代谁。 - 示例 metastore 是内存版。Polaris 示例用 in-memory metastore,重启即丢 catalog;生产要把 metastore 换成持久化后端(如 PostgreSQL),并给 RustFS 建专用 IAM 用户而非共用管理员凭证。
中性边界:示例的
vended-credentials-enabled=true让 Polaris 给 Trino 派发访问对象存储的临时凭据,凭证由 catalog 侧管理。生产里把 RustFS 的访问 Key 收进 Polaris 的凭证体系,比把静态 Key 写进每个 Trino 节点更干净,也更容易做轮换。
6. 总结与下一步
把这条湖仓链路的落地动作收一下:
- 存储用 RustFS(S3 兼容,默认 9000),catalog 用 Apache Polaris(Iceberg REST),查询用 Trino。
- Trino 的 Iceberg catalog 必须设
s3.endpoint=http://rustfs:9000与s3.path-style-access=true。 - 先用指南的 docker-compose 跑通 CREATE/INSERT/SELECT,确认数据文件落在 RustFS bucket。
- 生产把 Polaris metastore 换成持久化后端,RustFS 走专用 IAM 用户 + 凭证派发。
- 单表即席查询用 DuckDB,跨大表高并发用 Trino,两块存储共用 RustFS。
想先动手,最快的路子就是照 Polaris 官方那份 Trino 指南把四个容器拉起来,十分钟就能看到第一条SELECT从 RustFS 读出结果。RustFS 仓库在这:https://github.com/rustfs/rustfs ,把它接进你现有的 Iceberg 管线,比另起一套封闭存储省力得多。
深入学习 RustFS :RustFS
技术文档: RustFS 技术文档- 提供架构、安装指南和 API 参考。
GitHub 仓库: GitHub 仓库 - 获取源代码、提交问题或贡献代码。