Blog
trinofederationconnectorpushdowndata-platform

Trino 페더레이션 실전 — 이종 소스를 한 SQL 로 조인하기

Trino 의 정체성인 페더레이션을 실전 관점에서 다룹니다. Hive·Iceberg·PostgreSQL·MySQL·Kafka 커넥터 구성, 카탈로그를 넘나드는 조인, predicate/aggregate pushdown 의 동작과 한계, 그리고 페더레이션 쿼리를 빠르게 만드는 패턴을 정리합니다.

Data Dynamics2026年6月5日15 min read
This post is not yet translated. The original Korean version is shown below.

"이 분석, 데이터가 PostgreSQL 에도 있고 Iceberg 에도 있고 MySQL 에도 있는데… 다 긁어서 어딘가에 올려야 하나요?" — 이런 고민, 한 번쯤 해 보셨을 거예요. Trino 를 다른 SQL 엔진과 구분 짓는 단 하나의 기능을 꼽으라면 바로 페더레이션(Federation) 입니다. 오브젝트 스토리지의 Iceberg 테이블, 운영 DB 의 PostgreSQL, 레거시 MySQL, 실시간 Kafka 토픽을 하나의 SQL 로 조인할 수 있거든요. ETL 로 데이터를 한곳에 모으지 않고도 "있는 그 자리에서" 분석할 수 있죠.

이 글에서 배우는 것

  • Hive·Iceberg·PostgreSQL·MySQL·Kafka 커넥터를 붙이는 방법
  • 카탈로그를 넘나드는 크로스-소스 조인과 소스 간 적재(CTAS/INSERT)
  • pushdown 이 무엇이며 왜 페더레이션 성능의 핵심인지
  • pushdown 이 깨지는 패턴과 이를 피하는 SQL 작성법
  • 큰 테이블 조인·운영 DB 연결 시 실무 주의사항

이 글은 페더레이션을 실전 관점에서 다룹니다 — 커넥터를 어떻게 붙이는지, 카탈로그 간 조인은 어떻게 동작하는지, 그리고 가장 중요한 pushdown 의 동작과 한계를 이해해 느린 페더레이션 쿼리를 피하는 법까지.

1. 멘탈 모델 — 카탈로그 = 데이터 소스

Trino 를 처음 접한다면 이름 체계부터 짚어 두면 편합니다. Trino 의 이름 체계는 카탈로그.스키마.테이블 세 단계이고, 카탈로그 하나가 데이터 소스 하나에 대응합니다.

Loading diagram…

각 카탈로그는 etc/catalog/<이름>.properties 파일 하나로 정의됩니다. 파일을 추가하는 것만으로 새 데이터 소스가 SQL 표면에 등장합니다.

2. 커넥터 구성 — 소스별 properties

어떤 소스든 연결하는 방식은 같습니다 — etc/catalog/ 아래에 .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.com

Hive (기존 메타스토어 + HDFS/S3)

# etc/catalog/hive.properties
connector.name=hive
hive.metastore.uri=thrift://metastore:9083
fs.native-s3.enabled=true

PostgreSQL / 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
커넥터 부류대표특징
LakehouseIceberg, Delta, Hive, Hudi대용량 분석, manifest 기반 프루닝
RDBMSPostgreSQL, MySQL, Oracle, SQL Serverpushdown 강력, 운영 DB 부하 주의
NoSQLMongoDB, 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 로 가져오는 것입니다.

Loading diagram…
pushdown 종류내려가는 것효과
Predicate pushdownWHERE 조건소스에서 행 필터
Projection pushdown필요한 컬럼만전송 컬럼 축소
Aggregate pushdowncount, sum, GROUP BY소스에서 집계
Limit / TopN pushdownLIMIT, 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'

한 문장으로: pushdown 이 깨지는 가장 흔한 원인은 WHERE 절에서 컬럼을 함수로 감싸는 것입니다.

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 적재
운영 DBread replica, 부하·커넥션 가드레일

페더레이션은 Trino 의 가장 매력적인 기능이지만, 성능은 전적으로 pushdown 이 얼마나 동작하느냐에 달려 있습니다. EXPLAIN 으로 조건이 소스로 내려갔는지 확인하는 습관, 함수 래핑을 피하는 SQL 작성, 그리고 "반복되는 큰 조인은 페더레이션이 아니라 적재 신호"라는 판단 — 이 세 가지가 페더레이션을 실무에서 빠르게 굴리는 핵심입니다.

마치며 — 핵심 요약

  • 카탈로그 = 데이터 소스: etc/catalog/*.properties 파일 하나가 소스 하나를 SQL 표면에 올립니다.
  • 크로스-소스 조인은 SQL 한 줄: 카탈로그.스키마.테이블 표기만 맞추면 ETL 없이 이종 소스를 바로 조인할 수 있습니다.
  • pushdown 이 전부: 페더레이션 쿼리의 빠름·느림은 WHERE 와 집계가 소스로 내려가느냐 안 내려가느냐에서 결정됩니다.
  • 함수 래핑은 pushdown 의 적: WHERE date_trunc(...) = ... 대신 범위 비교를 쓰면 pushdown 이 살아납니다.
  • 반복 조인은 적재 신호: 같은 큰 테이블을 매번 운영 DB 에서 끌어온다면, 그건 Lakehouse 로 복제할 때가 된 것입니다.
  • 운영 DB 는 read replica + 가드레일 필수: 분석 쿼리가 운영 트랜잭션을 밀어내지 않도록 처음부터 설계해 두세요.

여러분의 이종 소스 분석 환경에 Trino 페더레이션이 든든한 기반이 되길 바랍니다!


이 글은 Trino 440번대 기준으로 작성되었습니다. 이종 데이터 소스 통합 분석이나 페더레이션/ELT 아키텍처 설계가 필요하시면 언제든 문의해 주세요.

— Data Dynamics 엔지니어링 팀