Trino 페더레이션 실전 — 이종 소스를 한 SQL 로 조인하기
Trino 의 정체성인 페더레이션을 실전 관점에서 다룹니다. Hive·Iceberg·PostgreSQL·MySQL·Kafka 커넥터 구성, 카탈로그를 넘나드는 조인, predicate/aggregate pushdown 의 동작과 한계, 그리고 페더레이션 쿼리를 빠르게 만드는 패턴을 정리합니다.
Trino 를 다른 SQL 엔진과 구분 짓는 단 하나의 기능을 꼽으라면 페더레이션(Federation) 입니다. 오브젝트 스토리지의 Iceberg 테이블, 운영 DB 의 PostgreSQL, 레거시 MySQL, 실시간 Kafka 토픽을 하나의 SQL 로 조인할 수 있습니다. ETL 로 데이터를 한곳에 모으지 않고도 "있는 그 자리에서" 분석합니다.
이 글은 페더레이션을 실전 관점에서 다룹니다 — 커넥터를 어떻게 붙이는지, 카탈로그 간 조인은 어떻게 동작하는지, 그리고 가장 중요한 pushdown 의 동작과 한계를 이해해 느린 페더레이션 쿼리를 피하는 법까지.
1. 멘탈 모델 — 카탈로그 = 데이터 소스
Trino 의 이름 체계는 카탈로그.스키마.테이블 세 단계입니다. 카탈로그 하나가 데이터 소스 하나에 대응합니다.
iceberg.analytics.events → 오브젝트 스토리지의 Iceberg 테이블
postgresql.crm.customers → 운영 PostgreSQL
mysql.legacy.orders → 레거시 MySQL
kafka.streams.clickstream → Kafka 토픽각 카탈로그는 etc/catalog/<이름>.properties 파일 하나로 정의됩니다. 파일을 추가하는 것만으로 새 데이터 소스가 SQL 표면에 등장합니다.
2. 커넥터 구성 — 소스별 properties
Iceberg (오브젝트 스토리지 Lakehouse)
# etc/catalog/iceberg.properties
connector.name=iceberg
iceberg.catalog.type=rest
iceberg.rest-catalog.uri=http://iceberg-rest:8181
fs.native-s3.enabled=true
s3.endpoint=https://s3.ap-northeast-2.amazonaws.comHive (기존 메타스토어 + HDFS/S3)
# etc/catalog/hive.properties
connector.name=hive
hive.metastore.uri=thrift://metastore:9083
fs.native-s3.enabled=truePostgreSQL / MySQL (RDBMS)
# etc/catalog/postgresql.properties
connector.name=postgresql
connection-url=jdbc:postgresql://pg-host:5432/crm
connection-user=trino
connection-password=${ENV:PG_PASSWORD}# etc/catalog/mysql.properties
connector.name=mysql
connection-url=jdbc:mysql://mysql-host:3306
connection-user=trino
connection-password=${ENV:MYSQL_PASSWORD}Kafka (실시간 스트림)
# etc/catalog/kafka.properties
connector.name=kafka
kafka.nodes=broker1:9092,broker2:9092
kafka.table-names=streams.clickstream
kafka.hide-internal-columns=false| 커넥터 부류 | 대표 | 특징 |
|---|---|---|
| Lakehouse | Iceberg, Delta, Hive, Hudi | 대용량 분석, manifest 기반 프루닝 |
| RDBMS | PostgreSQL, MySQL, Oracle, SQL Server | pushdown 강력, 운영 DB 부하 주의 |
| NoSQL | MongoDB, Cassandra | 스키마 매핑 |
| 검색/로그 | Elasticsearch, OpenSearch | 텍스트·로그 |
| 스트림 | Kafka | 실시간 토픽을 테이블로 |
| 웨어하우스 | BigQuery, Snowflake, Redshift | 클라우드 DW 페더레이션 |
3. 카탈로그를 넘나드는 조인
붙인 카탈로그들을 한 쿼리에서 그냥 조인하면 됩니다.
-- 오브젝트 스토리지 이벤트 × 운영 DB 고객 × 레거시 주문
SELECT
c.tier,
count(DISTINCT e.user_id) AS active_users,
sum(o.amount) AS revenue
FROM iceberg.analytics.events e
JOIN postgresql.crm.customers c ON e.user_id = c.id
JOIN mysql.legacy.orders o ON o.user_id = c.id
WHERE e.event_time >= TIMESTAMP '2026-06-01 00:00:00 UTC'
AND c.status = 'active'
GROUP BY c.tier;Trino 가 각 소스에서 데이터를 가져와 자신의 워커에서 조인·집계합니다. 데이터를 옮기는 ETL 없이 실시간 교차 분석이 가능합니다.
소스 간 데이터 이동 (CTAS / INSERT)
페더레이션은 조회뿐 아니라 소스 간 적재에도 쓰입니다.
-- 운영 DB 스냅샷을 Lakehouse 로
CREATE TABLE iceberg.analytics.customer_snapshot AS
SELECT * FROM postgresql.crm.customers;
-- 레거시 MySQL → Iceberg 증분 적재
INSERT INTO iceberg.analytics.orders
SELECT * FROM mysql.legacy.orders
WHERE updated_at >= current_date - INTERVAL '1' DAY;이것만으로 "DB → Lakehouse" 경량 ETL 이 됩니다. (NiFi 같은 도구를 쓰는 실시간 적재는 별도 글 "Trino Iceberg 테이블에 NiFi로 실시간 적재"에서 다뤘습니다.)
4. Pushdown — 페더레이션 성능의 핵심
페더레이션 쿼리의 성능을 좌우하는 단 하나의 개념이 pushdown 입니다. WHERE 필터·집계·정렬·LIMIT 을 소스 쪽으로 밀어 내려, 소스에서 미리 줄인 데이터만 Trino 로 가져오는 것입니다.
[pushdown 안 됨] RDBMS 의 1억 행 전체 ──네트워크──> Trino 가 받아서 필터 (느림)
[pushdown 됨] RDBMS 가 WHERE 로 1만 행만 ──네트워크──> Trino (빠름)| pushdown 종류 | 내려가는 것 | 효과 |
|---|---|---|
| Predicate pushdown | WHERE 조건 | 소스에서 행 필터 |
| Projection pushdown | 필요한 컬럼만 | 전송 컬럼 축소 |
| Aggregate pushdown | count, sum, GROUP BY | 소스에서 집계 |
| Limit / TopN pushdown | LIMIT, ORDER BY ... LIMIT | 소스에서 상위 N |
| Join pushdown | 같은 소스 내 조인 | 소스에서 조인(일부 커넥터) |
RDBMS 커넥터에서 특히 강력합니다 — Trino 가 WHERE/집계를 SQL 로 번역해 원본 DB 에 위임하므로, DB 의 인덱스까지 활용됩니다.
Pushdown 확인
EXPLAIN
SELECT count(*) FROM postgresql.crm.customers WHERE status = 'active';계획에서 TableScan 노드에 조건·집계가 붙어 소스로 내려갔는지 봅니다. 집계가 pushdown 되면 Trino 쪽에 별도 Aggregate 노드 없이 소스가 이미 집계한 결과를 받습니다.
5. Pushdown 이 깨지는 경우
pushdown 이 깨지면 소스의 전체 데이터를 끌어와 Trino 에서 처리하므로 급격히 느려집니다. 주요 원인:
| 패턴 | 결과 | 대안 |
|---|---|---|
WHERE 에 컬럼을 함수로 래핑 (LOWER(name)='x') | predicate pushdown 깨짐 | 소스가 이해하는 형태로, 또는 가공을 상수 쪽에 |
| Trino 전용 함수를 WHERE 에 사용 | 소스가 모르는 함수 → 못 내려감 | 표준 비교로 대체 |
| 소스 간 조인의 필터가 반대편에만 존재 | 한쪽 소스가 통째로 끌려옴 | 양쪽에 필터, dynamic filtering 활용 |
| 커넥터가 해당 집계를 미지원 | 집계 pushdown 실패 | 사전 집계 테이블 |
-- BAD: PostgreSQL 로 안 내려감 → 전체 끌어옴
WHERE date_trunc('day', created_at) = DATE '2026-06-01'
-- GOOD: 범위 비교 → pushdown
WHERE created_at >= TIMESTAMP '2026-06-01 00:00:00'
AND created_at < TIMESTAMP '2026-06-02 00:00:00'6. 큰 테이블끼리 페더레이션 조인할 때
서로 다른 소스의 큰 테이블 두 개를 조인하면, pushdown 으로도 한계가 있습니다. 양쪽을 모두 Trino 로 가져와 셔플해야 하기 때문입니다.
전략:
- 작은 쪽을 broadcast: 차원 테이블이 충분히 작으면 모든 워커에 복제(통계가 있어야 CBO 가 자동 선택). (조인 분배는 별도 글 "Trino Cost-Based Optimizer 깊이 보기"에서 다뤘습니다.)
- Dynamic Filtering: 작은 쪽(build) 결과로 동적 필터를 만들어 큰 쪽(probe) 스캔을 줄임. 페더레이션에서도 동작합니다.
- 자주 조인하는 운영 DB 큰 테이블은 Lakehouse 로 복제: 매번 운영 DB 를 때리는 대신, 야간 스냅샷을 Iceberg 로 내려두고 거기에 조인. 운영 DB 부하도 줄어듭니다.
원칙: 페더레이션은 "실시간으로 최신 운영 데이터를 끌어와야 할 때" 빛납니다. 반복적으로 같은 큰 테이블을 조인한다면, 그건 페더레이션보다 Lakehouse 로의 적재(ELT) 신호입니다.
7. 운영 DB 를 페더레이션할 때의 주의
RDBMS 커넥터는 강력하지만, 운영 DB 에 부하를 줄 수 있습니다.
- 분석 쿼리가 운영 트랜잭션과 자원을 경합하지 않도록, 가능하면 읽기 복제본(read replica) 을 가리키세요.
- 큰 풀스캔이 운영 DB 를 마비시키지 않도록 Trino 쪽
query.max-scan-physical-bytes가드레일과 소스 DB 의 statement timeout 을 함께 둡니다. - 커넥터의 동시 연결 수(connection pool)를 제한해 운영 DB 커넥션을 고갈시키지 않게 합니다.
8. 페더레이션 성능 체크리스트
-
EXPLAIN으로 WHERE/집계가 소스로 pushdown 됐는지 확인 - WHERE 절에 컬럼 함수 래핑 제거 (범위 비교로)
- 큰 차원 테이블에 통계(
ANALYZE) → broadcast 자동 선택 - 반복 조인되는 운영 DB 테이블은 Lakehouse 로 복제 검토
- 운영 DB 는 read replica 연결, connection pool 제한
- dynamic filtering 동작 확인 (
EXPLAIN의 dynamicFilter) - 스캔 가드레일·소스 timeout 설정
9. 정리
| 개념 | 요점 |
|---|---|
| 카탈로그 | 데이터 소스 1개 = properties 파일 1개 |
| 조인 | 카탈로그.스키마.테이블 을 그냥 조인 |
| 소스 간 적재 | CTAS/INSERT 로 경량 ELT |
| pushdown | 페더레이션 성능의 핵심 — 필터·집계를 소스로 |
| 깨짐 회피 | 함수 래핑 금지, 표준 비교 |
| 큰 조인 | broadcast·dynamic filtering, 반복되면 Lakehouse 적재 |
| 운영 DB | read replica, 부하·커넥션 가드레일 |
페더레이션은 Trino 의 가장 매력적인 기능이지만, 성능은 전적으로 pushdown 이 얼마나 동작하느냐에 달려 있습니다. EXPLAIN 으로 조건이 소스로 내려갔는지 확인하는 습관, 함수 래핑을 피하는 SQL 작성, 그리고 "반복되는 큰 조인은 페더레이션이 아니라 적재 신호"라는 판단 — 이 세 가지가 페더레이션을 실무에서 빠르게 굴리는 핵심입니다.
이 글은 Trino 440번대 기준으로 작성되었습니다. 이종 데이터 소스 통합 분석이나 페더레이션/ELT 아키텍처 설계가 필요하시면 언제든 문의해 주세요.
— Data Dynamics 엔지니어링 팀