Trino 관측성 — JMX 메트릭, Web UI, 그리고 느린 쿼리 진단
프로덕션 Trino 를 안정적으로 운영하려면 무엇을 모니터링해야 하는가. JMX 메트릭과 Prometheus 수집, Web UI 로 쿼리 분석, system.runtime 테이블 활용, 이벤트 리스너로 쿼리 감사·이력 적재, 그리고 느린 쿼리를 진단하는 절차를 정리합니다.
Trino 클러스터가 느려지거나 쿼리가 실패할 때, "왜?"에 답할 수 있어야 운영이 됩니다. 관측성이 없으면 사용자 민원에 끌려다니며 추측으로 대응하게 됩니다. 다행히 Trino 는 풍부한 관측 수단 — JMX 메트릭, Web UI, system 테이블, 이벤트 리스너 — 을 기본 제공합니다.
이 글은 무엇을 모니터링해야 하는지, 어떻게 수집·시각화하는지, 그리고 느린 쿼리를 만났을 때 어떤 순서로 파고들지를 정리합니다.
1. 관측성 4계층
① JMX 메트릭 → Prometheus/Grafana 로 시계열·알림 (클러스터 건강)
② Web UI → 실시간 쿼리·스테이지 분석 (단건 진단)
③ system 테이블 → SQL 로 현황·이력 조회 (자동화·리포트)
④ 이벤트 리스너 → 쿼리 시작/완료 이벤트 적재 (감사·장기 분석)| 계층 | 답하는 질문 | 도구 |
|---|---|---|
| JMX | 클러스터가 건강한가? 추세는? | Prometheus, Grafana |
| Web UI | 이 쿼리가 왜 느린가? | 코디네이터 Web UI |
| system 테이블 | 지금 무엇이 돌고 있나? | system.runtime.* |
| 이벤트 리스너 | 어제 누가 무슨 쿼리를 했나? | 이벤트 리스너 → 외부 저장소 |
2. JMX 메트릭과 Prometheus
Trino 는 내부 상태를 JMX 로 노출하고, JMX 를 SQL 로 조회하는 jmx 카탈로그도 제공합니다. 프로덕션에서는 보통 Prometheus 로 수집 → Grafana 로 시각화 → Alertmanager 로 알림을 구성합니다.
코디네이터는 /metrics 엔드포인트(또는 JMX exporter)로 Prometheus 포맷 메트릭을 내보낼 수 있습니다.
# Prometheus scrape 예시
scrape_configs:
- job_name: trino
metrics_path: /metrics
static_configs:
- targets: ['trino-coordinator:8080']꼭 봐야 할 핵심 지표
| 지표 영역 | 무엇을 보나 | 경보 신호 |
|---|---|---|
| 쿼리 수 | running / queued / blocked | queued 가 계속 쌓임 → 자원 부족 |
| 쿼리 결과 | completed / failed 비율 | 실패율 급증 |
| 클러스터 메모리 | 사용량 / 예약량 | 상한 근접 → OOM 위험 |
| 워커 노드 수 | active worker | 감소 → 디스커버리·노드 장애 |
| CPU | 워커 CPU 사용률 | 지속 포화 → 증설/스케일 |
| GC | GC pause 시간·빈도 | 길어짐 → 힙 압박 |
| 스풀(FTE) | exchange I/O | 급증 → 재시도 과다 |
queued 쿼리 수와 클러스터 메모리, 워커 노드 수, 이 셋을 대시보드 맨 위에 두는 것을 권장합니다 — 대부분의 장애가 이 세 지표에서 먼저 드러납니다.
jmx 카탈로그로 즉석 조회
-- 클러스터 메모리 풀 상태를 SQL 로
SELECT node, freebytes, maxbytes
FROM jmx.current."trino.memory:name=general,type=memorypool";3. Web UI — 단건 쿼리 진단의 핵심
코디네이터 Web UI(기본 8080/8443)는 실시간 쿼리 목록과 각 쿼리의 상세 분석을 제공합니다. 느린 쿼리 한 건을 파고들 때 가장 강력합니다.
Query Detail 에서 볼 것:
| 항목 | 의미 | 진단 |
|---|---|---|
| Peak Memory | 쿼리 최대 메모리 | 상한 근접 → 튜닝 1순위 |
| Stage별 시간 | 어느 스테이지가 오래 걸리나 | 병목 스테이지 식별 |
| Input/Output rows | 데이터가 어디서 폭증하나 | 조인 부풀림 |
| Spilled Data | spill 발생 여부·양 | 메모리 부족 신호 |
| Splits (스케줄링) | 워커별 split 분배 | 데이터 스큐(skew) |
데이터 스큐 진단: 한 워커의 split·처리 시간만 유독 길다면, 특정 키에 데이터가 몰린 것입니다. 조인 키 분포를 의심하고, 필요하면 파티션/버킷 설계를 재검토하세요.
4. system 테이블 — SQL 로 현황 조회
system.runtime 스키마로 클러스터 상태를 SQL 로 조회할 수 있어, 자동화·정기 리포트에 유용합니다.
-- 지금 실행/대기 중인 쿼리 (메모리 큰 순)
SELECT query_id, state, user, resource_group_id,
total_memory_reservation, elapsed_time, query
FROM system.runtime.queries
WHERE state IN ('RUNNING', 'QUEUED')
ORDER BY total_memory_reservation DESC;
-- 활성 워커 노드
SELECT node_id, http_uri, node_version, state
FROM system.runtime.nodes;
-- 오래 도는 쿼리 찾기 (예: 10분 초과)
SELECT query_id, user, elapsed_time, query
FROM system.runtime.queries
WHERE state = 'RUNNING' AND elapsed_time > INTERVAL '10' MINUTE
ORDER BY elapsed_time DESC;-- 폭주 쿼리 강제 종료
CALL system.runtime.kill_query(query_id => '20260605_120000_00001_abcde',
message => 'admin killed: runaway scan');5. 이벤트 리스너 — 쿼리 감사와 장기 분석
Web UI·system 테이블은 휘발성입니다(코디네이터 재시작·이력 보존 한도). 장기 분석·감사를 위해서는 이벤트 리스너로 쿼리 시작/완료 이벤트를 외부에 적재합니다.
# etc/event-listener.properties
event-listener.name=... # 예: HTTP, Kafka, 또는 커스텀 플러그인이벤트에는 쿼리 텍스트, 사용자, 소스, 실행 시간, 스캔 바이트, 메모리, 성공/실패, 오류 코드 등이 담깁니다. 이를 Kafka/HTTP 로 받아 Iceberg 테이블에 적재하면 — Trino 자신으로 — 다음 같은 분석을 할 수 있습니다.
-- 어제 가장 비싼(스캔량 많은) 쿼리 Top 20
SELECT user, scanned_bytes / 1e9 AS scanned_gb, elapsed_ms, query
FROM iceberg.audit.query_log
WHERE event_date = current_date - INTERVAL '1' DAY
ORDER BY scanned_bytes DESC
LIMIT 20;
-- 사용자/소스별 실패율 추세
SELECT user, count(*) AS total,
count_if(state = 'FAILED') AS failed,
count_if(state = 'FAILED') * 1.0 / count(*) AS fail_rate
FROM iceberg.audit.query_log
WHERE event_date >= current_date - INTERVAL '7' DAY
GROUP BY user
ORDER BY fail_rate DESC;이 쿼리 로그는 보안 감사, 비용 분석(누가 자원을 많이 쓰나), 그리고 Resource Group 정책 튜닝의 근거가 됩니다.
6. 느린 쿼리 진단 절차
증상을 만났을 때 순서대로 좁혀 들어갑니다.
1. 클러스터 전체인가, 이 쿼리만인가? → JMX 대시보드 (queued/메모리/워커 수)
│ 전체 문제면 → 자원 부족·노드 장애 (증설/스케일/디스커버리 점검)
│ 단건 문제면 ↓
2. 어느 스테이지가 병목인가? → Web UI Query Detail (stage별 시간)
│
3. 추정 vs 실제 행 수가 어긋나는가? → EXPLAIN ANALYZE (통계 문제 → ANALYZE)
│
4. 데이터 스큐인가? → Web UI splits (워커별 편차)
│
5. spill 이 터지나? → Web UI Spilled Data (메모리 부족)
│
6. pushdown/프루닝이 깨졌나? → EXPLAIN (함수 래핑·통계)(EXPLAIN/통계 상세는 별도 글 "Trino Cost-Based Optimizer 깊이 보기", 메모리·spill 은 "Trino 메모리 관리와 Resource Groups"를 참고하세요.)
7. 증상 → 지표 → 처방 빠른 표
| 증상 | 먼저 볼 지표 | 처방 |
|---|---|---|
| 쿼리가 큐에 쌓임 | queued queries, 동시성 한도 | Resource Group 조정, 워커 증설 |
| 클러스터 전체 느림 | 워커 CPU, 메모리, 노드 수 | 스케일아웃, 노드 장애 복구 |
| 특정 쿼리만 느림 | Web UI stage 시간 | 병목 스테이지 튜닝 |
| 간헐적 OOM | 클러스터 메모리, peak memory | spill, 메모리 상한, 쿼리 최적화 |
| 워커 수 들쭉날쭉 | active worker, GC | 디스커버리·힙·노드풀 점검 |
| 한 쿼리가 자원 독점 | runtime.queries | kill_query + Resource Group |
| 실패율 급증 | failed 비율, 오류 코드 | 이벤트 로그로 오류 패턴 분석 |
8. 알림(Alerting) 권장 규칙
Grafana/Alertmanager 로 최소한 다음을 걸어두세요.
- 활성 워커 수가 기대치 아래로 N분 지속
- 클러스터 메모리 사용률 > 85% N분 지속
- queued 쿼리 수 > 임계값 N분 지속
- 쿼리 실패율 > 임계값
- 코디네이터 헬스체크(
/v1/info) 실패
9. 정리
| 계층 | 용도 | 핵심 |
|---|---|---|
| JMX + Prometheus | 클러스터 건강·추세·알림 | queued·메모리·워커 수 |
| Web UI | 단건 쿼리 심층 분석 | peak memory, stage, 스큐, spill |
| system.runtime | 실시간 현황·자동화 | queries, nodes, kill_query |
| 이벤트 리스너 | 감사·장기·비용 분석 | 쿼리 로그를 Iceberg 로 적재 |
Trino 관측성의 핵심은 "전체인가 단건인가"를 먼저 가르고, JMX 대시보드 → Web UI → EXPLAIN ANALYZE 순으로 좁혀 들어가는 것입니다. 여기에 이벤트 리스너로 쿼리 이력을 쌓아두면, 사후 감사와 비용 분석은 물론 Resource Group 정책을 데이터 기반으로 튜닝할 수 있습니다. 추측이 아니라 지표로 운영하는 것 — 그것이 안정적인 Trino 클러스터의 조건입니다.
이 글은 Trino 440번대 기준으로 작성되었습니다. Trino 모니터링 대시보드 구축이나 쿼리 감사·비용 분석 체계 수립이 필요하시면 언제든 문의해 주세요.
— Data Dynamics 엔지니어링 팀