Blog
trinofederationconnectorpushdowndata-platform

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

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

Data Dynamics2026년 6월 5일15 min read

"이 분석, 데이터가 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 엔지니어링 팀