Trino 캐싱 전략 — 파일시스템 캐시, 메타데이터 캐시, 그리고 한계
오브젝트 스토리지를 쓰는 Trino 에서 반복 I/O 와 메타스토어 RTT 가 지연의 주범입니다. 파일시스템(데이터) 캐시, Hive 메타데이터 캐시, 그리고 Trino 가 결과 캐시를 제공하지 않는 이유와 대안을 정리합니다.
Trino 는 데이터를 소유하지 않고 오브젝트 스토리지(S3/GCS/Azure)나 외부 시스템에서 매번 읽어옵니다. 이 구조는 유연하지만, 같은 데이터를 반복해서 네트워크로 끌어오는 비용과 메타스토어 왕복 지연이 누적되면 대화형 분석의 응답성을 떨어뜨립니다. 캐싱은 이 두 비용을 줄이는 핵심 수단입니다.
이 글은 Trino 의 캐싱을 데이터(파일시스템) 캐시와 메타데이터 캐시 두 축으로 정리하고, "왜 Trino 에는 결과 캐시가 없는가"라는 자주 나오는 질문에도 답합니다.
1. 어디서 시간이 새는가
[쿼리 1회]
메타데이터 조회 ──> 메타스토어/카탈로그 왕복 (RTT)
│
파일 목록·통계 ──> manifest / HMS 읽기
│
데이터 스캔 ──> 오브젝트 스토리지에서 Parquet/ORC 읽기 (네트워크 대역)| 비용 | 원인 | 캐싱 수단 |
|---|---|---|
| 메타데이터 RTT | 매 쿼리마다 메타스토어 조회 | 메타데이터 캐시 |
| 반복 데이터 I/O | 인기 데이터를 매번 원격에서 읽음 | 파일시스템(데이터) 캐시 |
| 동일 쿼리 재실행 | 결과를 매번 재계산 | (결과 캐시 없음 → 대안 필요) |
2. 파일시스템 캐시 — 데이터를 워커 로컬에 캐싱
Trino 의 파일시스템 캐시는 오브젝트 스토리지에서 읽은 데이터 파일(블록)을 워커의 로컬 디스크(SSD)에 캐싱합니다. 같은 데이터를 다시 읽을 때 원격 대신 로컬에서 읽어 지연과 네트워크 비용을 줄입니다.
# etc/config.properties (또는 카탈로그별)
fs.cache.enabled=true
fs.cache.directories=/data1/trino-cache,/data2/trino-cache
fs.cache.max-sizes=200GB,200GB| 항목 | 설명 |
|---|---|
| 캐시 대상 | 오브젝트 스토리지의 데이터 파일 블록 |
| 저장 위치 | 워커 로컬 SSD (여러 경로 분산 권장) |
| 효과 | 반복 스캔되는 핫 데이터의 원격 I/O 제거 |
| 일관성 | Iceberg 는 불변 데이터 파일 모델이라 캐시 무효화가 단순 |
왜 Iceberg 와 궁합이 좋은가
Iceberg 의 데이터 파일은 불변(immutable) 입니다. 한 번 쓰인 파일은 바뀌지 않고, 변경은 새 파일 + 새 스냅샷으로 표현됩니다. 따라서 "캐시한 파일이 원본과 달라졌을까?"를 걱정할 필요가 없습니다 — 파일 경로가 같으면 내용도 같습니다. 이 불변성 덕분에 파일시스템 캐시가 안전하고 효과적입니다.
노드 어피니티 (Soft Affinity)
캐시가 효과를 보려면 같은 파일을 가급적 같은 워커가 읽어야 합니다. 그렇지 않으면 모든 워커에 같은 데이터가 중복 캐싱되어 효율이 떨어집니다. Trino 는 split 을 파일 기준으로 일관된 워커에 배정하는 soft affinity 스케줄링을 사용해 캐시 적중률을 높입니다.
3. 메타데이터 캐시 — 메타스토어 왕복 줄이기
3.1 Hive 커넥터 메타데이터 캐시
Hive 커넥터는 매 쿼리마다 Hive Metastore(HMS)에 스키마·파티션·통계를 조회합니다. 파티션이 많거나 HMS 가 멀면 이 RTT 가 쌓입니다. 캐시로 완화합니다.
# etc/catalog/hive.properties
hive.metastore-cache-ttl=10m
hive.metastore-cache-maximum-size=10000
hive.metastore-refresh-interval=1m| 파라미터 | 의미 |
|---|---|
hive.metastore-cache-ttl | 캐시 항목 유효 기간 |
hive.metastore-refresh-interval | 백그라운드 갱신 주기 |
hive.metastore-cache-maximum-size | 캐시 최대 항목 수 |
트레이드오프: TTL 동안 외부 도구가 메타데이터를 바꿔도 Trino 가 옛 정보를 볼 수 있습니다. 강제로 비우려면:
CALL system.flush_metadata_cache();Cloudera/Impala 에서 넘어온 분들이 흔히 오해하는 지점: 이 캐시는 Impala 의
catalogd캐시와 비슷한 "사람이 관리하는 캐시"입니다. 반면 Iceberg 커넥터는 스냅샷 모델이라 이런 TTL 캐시가 기본적으로 불필요합니다 — 커밋이 곧 가시성입니다. 그래서 Iceberg 로 가면 메타데이터 캐시 고민 자체가 줄어듭니다.
3.2 Iceberg 의 메타데이터 모델
Iceberg 는 파티션·파일 통계를 HMS RPC 가 아니라 manifest 파일(스토리지)에서 읽습니다. HMS 왕복이 없으니 메타데이터 병목이 구조적으로 작습니다. 따라서 Iceberg 테이블에서는 파일시스템 캐시(manifest 파일도 캐싱)로 충분한 경우가 많습니다.
4. 결과 캐시 — 왜 Trino 에는 없는가
"같은 쿼리를 또 던지면 결과를 캐시에서 바로 주면 안 되나?"는 자주 나오는 질문입니다. Trino 는 기본적으로 쿼리 결과 캐시를 제공하지 않습니다. 이유:
- Trino 는 페더레이션 엔진입니다. 소스 데이터가 외부 시스템에서 언제든 바뀔 수 있어, "캐시된 결과가 아직 유효한가"를 일반적으로 보장하기 어렵습니다.
- 결과 정합성(stale read) 위험을 엔진 차원에서 떠안기보다, 일관성 보장을 데이터 계층에 맡기는 설계입니다.
대신 다음 대안이 있습니다.
| 대안 | 방법 | 적합 |
|---|---|---|
| Materialized View | 자주 쓰는 집계를 사전 계산해 테이블로 보관, 주기적 refresh | 반복되는 무거운 집계 |
| 사전 집계 테이블(CTAS) | 일배치로 요약 테이블 생성 | 대시보드 백엔드 |
| BI 도구 캐시 | Superset/Tableau 의 자체 결과 캐시 | 대시보드 응답성 |
| 파일시스템 캐시 | 결과가 아닌 입력 데이터 I/O 절감 | 반복 스캔 |
Materialized View
CREATE MATERIALIZED VIEW iceberg.analytics.daily_active_users AS
SELECT date(event_time) AS d, count(DISTINCT user_id) AS dau
FROM iceberg.analytics.events
GROUP BY date(event_time);
-- 주기적 갱신 (스케줄러에서)
REFRESH MATERIALIZED VIEW iceberg.analytics.daily_active_users;Iceberg 커넥터의 materialized view 는 결과를 실제 테이블로 저장하고, 원본이 갱신되면 stale 상태를 추적합니다. 대시보드처럼 "같은 무거운 집계를 반복"하는 패턴에 결과 캐시의 실질적 대안이 됩니다.
5. 캐싱이 효과 없는/역효과인 경우
| 상황 | 이유 |
|---|---|
| 매번 다른 데이터를 스캔(거의 중복 없음) | 파일시스템 캐시 적중률 0, 디스크만 낭비 |
| 워커 로컬 디스크가 느림/작음 | 캐시 I/O 가 원격보다 못함 |
| 외부 도구가 메타데이터를 자주 변경 | 메타데이터 TTL 캐시가 stale read 유발 |
| 일회성 대용량 배치 | 재사용이 없어 캐시 의미 없음 |
| 데이터가 자주 바뀌는 테이블에 결과 캐시 흉내 | 정합성 위험 |
캐시는 "반복 접근되는 핫 데이터/메타데이터"가 있을 때 빛납니다. 워크로드가 매번 새로운 데이터를 훑는다면 캐시는 비용만 늘립니다.
6. 구성 가이드 — 워크로드별 권장
| 워크로드 | 파일시스템 캐시 | 메타데이터 캐시 | 결과 대안 |
|---|---|---|---|
| 대화형 BI(핫 데이터 반복) | 켜기 (큰 로컬 SSD) | Iceberg면 불필요 / Hive면 짧은 TTL | Materialized View, BI 캐시 |
| 대시보드 백엔드 | 켜기 | — | 사전 집계 테이블 |
| 대용량 ETL(일회성 스캔) | 끄기 | — | 불필요 |
| Hive + 많은 파티션 | 켜기 | TTL + refresh + flush 절차 | — |
7. 정리
| 캐시 종류 | 줄이는 비용 | 핵심 설정 | 주의 |
|---|---|---|---|
| 파일시스템(데이터) | 반복 원격 I/O | fs.cache.* + soft affinity | 로컬 SSD 필요, 핫 데이터일 때만 |
| 메타데이터(Hive) | 메타스토어 RTT | hive.metastore-cache-ttl | stale read, flush_metadata_cache() |
| 결과 캐시 | 재계산 | (없음) | Materialized View·사전집계로 대체 |
Trino 캐싱의 핵심 원칙은 두 가지입니다. 첫째, 데이터 I/O 는 파일시스템 캐시로, 메타데이터 RTT 는 메타데이터 캐시로 줄이되, 반복 접근이 있는 워크로드에서만 켜는 것. 둘째, 결과 캐시가 없다는 사실을 받아들이고, 반복되는 무거운 집계는 Materialized View 나 사전 집계 테이블로 대체하는 것. Iceberg 의 불변 파일·스냅샷 모델은 이 캐싱 전략을 더 단순하고 안전하게 만들어 줍니다.
이 글은 Trino 440번대 기준으로 작성되었습니다. 대화형 분석의 응답성 개선이나 캐싱·사전집계 설계가 필요하시면 언제든 문의해 주세요.
— Data Dynamics 엔지니어링 팀