Trino 是一款面向海量数据的分布式 SQL 查询引擎,最大的特点是“联邦查询”——你可以用一条标准 SQL,同时查询 MySQL、PostgreSQL、Hive、Iceberg、对象存储里的 Parquet 等多种数据源,并在引擎内部完成跨源 JOIN 与聚合。对于数据散落在多个业务库和数据湖里的团队,Trino 让你不必先做 ETL 搬运,就能直接做统一分析。
一、为什么需要 Trino:数据散落各处
真实业务里,订单在 MySQL、客户在 PostgreSQL、行为日志在对象存储的 Parquet 文件、历史明细在 Hive 表——想做一次“某地区高价值客户的近期订单分析”,传统做法要先写同步任务把数据搬到一个库,再写 SQL。链路长、时效差、还得养一套调度。
Trino 的思路不同:它自己不存储数据,而是通过 Connector 直连各个数据源,把计算下推到源头或拉到内存里做 MPP 并行计算。你只要会写 SQL,就能把“跨库关联”交给引擎。这也是它和 ClickHouse、TiDB 这类“自带存储”的数据库本质区别。
举个具体例子:电商团队想分析“华东地区近 30 天复购客户的客单价分布”。订单在 MySQL 的 sales 库,客户标签在 PostgreSQL 的 crm 库,行为明细在对象存储的 Parquet。没有 Trino 时,你得写两个抽取任务加一个 Python/Spark 关联脚本,数据延迟至少 T+1;有了 Trino,这三个源都是 catalog,一条 SQL 几分钟出结果,分析师自助即可完成,不必排队等数据工程排期。
二、Trino 是什么:MPP 与存储计算分离
2.1 Coordinator 与 Worker 架构
Trino 集群由一个 Coordinator(调度与解析 SQL、生成执行计划)和多个 Worker(真正干活的并行计算节点)组成。客户端连 Coordinator 的 8080 端口提交查询,Coordinator 把查询切成 Stage 和 Task 分发到 Worker,结果逐级汇聚返回。
2.2 Connector 插件体系
每一种数据源对应一个 Connector:mysql、postgresql、iceberg、delta-lake、hive、clickhouse 等。只要在 etc/catalog/ 下写好一份 properties 文件,就多了一个可通过 catalog.schema.table 三段式访问的源。新增数据源对业务零侵入。
Connector 生态是 Trino 的最大护城河:官方和社区已覆盖绝大多数关系型数据库、数据湖表格式和对象存储。这意味着你接入一套新系统时,通常只需要一份配置文件,而不是一套定制开发。对一个需要对接十几种数据源的中台团队来说,这点尤为关键。
三、用 Docker Compose 快速起一套 Trino
本地验证最省事的方式是 Docker Compose。下面给一个单 Coordinator + 单 Worker 的最小可跑配置,目录结构为 ./etc 放配置、镜像用官方 trinodb/trino。关于 Compose 编排本身可参考 Docker Compose 实战,容器与镜像基础可看 Docker 实战。
version: "3"
services:
trino-coordinator:
image: trinodb/trino:447
container_name: trino-coordinator
ports:
- "8080:8080"
volumes:
- ./etc:/etc/trino
trino-worker:
image: trinodb/trino:447
container_name: trino-worker
command: /usr/lib/trino/bin/run-trino
volumes:
- ./etc:/etc/trino
Coordinator 的 etc/config.properties 至少要声明自己是协调者并给出 discovery 地址:
coordinator=true
node-scheduler.include-coordinator=true
http-server.http.port=8080
discovery.uri=http://trino-coordinator:8080
启动后等日志出现 SERVER STARTED,即可进入 CLI:
docker compose up -d
docker logs -f trino-coordinator
docker exec -it trino-coordinator trino
四、配置 Connector:打通 MySQL 与 PostgreSQL
Trino 通过 etc/catalog/*.properties 挂载数据源。下面分别配置一个 MySQL(订单库)和一个 PostgreSQL(CRM 库),连接账号建议给只读权限。
# etc/catalog/mysql.properties
connector.name=mysql
connection-url=jdbc:mysql://mysql-host:3306
connection-user=trino_ro
connection-password=changeme
# etc/catalog/postgresql.properties
connector.name=postgresql
connection-url=jdbc:postgresql://pg-host:5432/crm
connection-user=trino_ro
connection-password=changeme
如果需要查询数据湖里的 Iceberg 表(例如对接 Hive Metastore),再挂一个 iceberg catalog 即可:
# etc/catalog/iceberg.properties
connector.name=iceberg
iceberg.catalog.type=hive_metastore
hive.metastore.uri=thrift://hive-metastore:9083
五、联邦查询实战:跨源 JOIN
配置好后,表名采用 catalog.schema.table 三段式。下面这条 SQL 把 MySQL 的订单和 PostgreSQL 的客户直接关联,无需任何中间同步:
从执行角度看,Trino 会把这条查询拆成多个 Stage:先在 MySQL 和 PostgreSQL 两侧各做本地过滤与投影(下推),再把需要的列数据流式拉到 Worker 做哈希 JOIN 和聚合。整个过程对用户透明,你拿到的只是一张结果表。这也是“联邦”二字的实质——计算靠近数据,而不是把全部数据搬到一个中心仓库。
实际生产里,这种写法能替代相当一部分临时的数据搬运脚本。过去分析师要等数据工程把订单和 CRM 同步到同一个库,现在他们自己就能查,响应从“天”缩短到“分钟”。
SELECT
c.customer_name,
o.order_id,
SUM(o.amount) AS total_amount
FROM mysql.sales.orders o
JOIN postgresql.crm.customers c
ON o.customer_id = c.id
WHERE o.created_at >= DATE '2026-01-01'
GROUP BY c.customer_name, o.order_id
ORDER BY total_amount DESC
LIMIT 20;
对 Iceberg 数据湖同样可以用标准 SQL 分析,例如统计某天的区域访问量:
SELECT region, COUNT(*) AS pv
FROM iceberg.analytics.user_events
WHERE event_date = DATE '2026-10-12'
GROUP BY region;
想验证表是否被正确识别,可先用 SHOW CATALOGS; 和 SHOW TABLES FROM mysql.sales; 探查元数据。PostgreSQL 的建表与索引基础可复习 PostgreSQL 实战,数据湖表格式可延伸阅读 Apache Iceberg 实战。
六、性能调优:内存、下推与分区
Trino 是内存密集型引擎,查询被切成的 Task 在内存里流式处理。内存给太小会报 “Query exceeded distributed memory limit”,给太大又可能压垮节点。下面是一份常用调优对照:
| 维度 | 配置项 | 建议 |
| 单节点查询内存 | query.max-memory-per-node | 设为单节点 JVM 堆的 10%–20% |
| 集群总内存 | query.max-memory | ≈ worker 数 × 单节点上限 |
| 谓词下推 | 各 connector 默认开启 | 复杂过滤确认下推生效 |
| 分区裁剪 | 建表时合理 partition | 查询带分区列过滤减少扫描 |
| 任务并发 | task.concurrency | 通常为 CPU 核数的 1–2 倍 |
善用 EXPLAIN 和 EXPLAIN ANALYZE 看执行计划,重点确认过滤条件和聚合有没有下推到数据源,而不是把整张表拉回内存。
内存配置是 Trino 调优里最容易踩坑的地方:JVM 堆不能全给查询用,要留出给 coordinator 调度和 worker 网络缓冲的空间。经验值是单节点查询内存上限取堆的 10%–20%,集群总上限再按 worker 数相乘。一旦设置过小,复杂查询频繁熔断;设置过大,单个失控查询可能拖垮整节点。
七、Trino 与 ClickHouse / TiDB 怎么选
三者都能做分析,但定位不同。Trino 胜在“不搬数据、跨源即查”;ClickHouse 胜在“自有列式存储、单表聚合极快”;TiDB 胜在“兼容 MySQL 协议、自带存储与事务”。选型时按数据是否已经在统一存储里来决定:
| 维度 | Trino | ClickHouse | TiDB |
| 定位 | 联邦查询 / 即席分析 | 列式 OLAP 存储 | 分布式 HTAP 数据库 |
| 存储 | 不存数据,连源 | 自有列式存储 | 自有行/列存储 |
| 强项 | 跨源 JOIN | 单表聚合极快 | MySQL 兼容事务 |
| 典型场景 | 数据湖 / 跨库分析 | 日志 / 指标分析 | 业务库水平扩展 |
想深入列式分析可看 ClickHouse 实战,分布式 SQL 另一条路线可看 TiDB 实战。Trino 常作为“统一查询入口”和它们并存:热数据留在 ClickHouse,跨源关联交给 Trino。
八、常见问题排障
1. 查询报内存超限。 调大 query.max-memory / query.max-memory-per-node,或改写查询减少单次处理量(加分区过滤、先聚合再 JOIN)。
2. Connector 连不上源库。 检查 connection-url 端口、账号密码、以及源库是否把 Trino 节点 IP 加进白名单;JDBC 驱动已随 Connector 内置,一般无需额外安装。
3. 查询比预期慢很多。 先用 EXPLAIN ANALYZE 看是否发生全表扫描或下推失效;确认 connector 支持的分区/谓词下推开关已开启。
九、结语
Trino 的价值不在“又一个数据库”,而在“让数据待在原地也能被统一查询”。当你的分析需求跨越多个异构数据源、又不想维护沉重的同步管道时,用 Docker Compose 起一套 Trino、配好 Connector,就能用熟悉的 SQL 把多源数据连成一张逻辑大表。它和 ClickHouse、TiDB 并非替代关系,而是分析体系里“联邦入口”那一块拼图。
落地建议很直接:先从一个只读的“分析账号 + 两个业务库 catalog”开始,跑通一两条真实联邦查询,让团队感受“跨库即查”的爽感;再逐步接入数据湖 Iceberg/Parquet,把 T+1 的报表查询迁移到即席分析。等规模上来,再考虑多 Worker 横向扩容和资源队列隔离。小步快跑,比一上来追求“完美架构”更稳。




