왜 테이블 유지 보수가 필요한가요?
Delta Lake 테이블은 시간이 지나면서 두 가지 문제가 자연스럽게 발생합니다.- 소형 파일 누적: 잦은 INSERT, 스트리밍 수집으로 인해 작은 파일이 수천~수만 개 쌓입니다
- 불필요한 파일 잔류: UPDATE/DELETE 후 이전 버전의 파일이 계속 남아 스토리지 비용이 증가합니다
소형 파일 문제 (Small File Problem)
💡 Small File Problem(소형 파일 문제) 이란 테이블에 매우 작은 크기의 파일이 대량으로 쌓이는 현상입니다. 각 파일을 열고 닫는 I/O 오버헤드가 누적되어 쿼리 성능이 심각하게 저하됩니다.
언제 발생하나요?
| 원인 | 설명 |
|---|---|
| Structured Streaming | 마이크로 배치마다 소량의 데이터를 쓰면 작은 파일이 생성됩니다 |
| 잦은 INSERT | 소량 데이터를 빈번하게 INSERT하면 파일이 쪼개집니다 |
| 과도한 파티셔닝 | 파티션 수가 많으면 각 파티션의 파일이 매우 작아집니다 |
| 많은 동시 쓰기 | 여러 작업이 동시에 테이블에 쓰면 파일이 분산됩니다 |
OPTIMIZE (데이터 압축)
동작 원리
OPTIMIZE는 여러 개의 작은 파일을 읽어 적절한 크기의 큰 파일로 병합(bin-packing) 합니다. 기본 목표 파일 크기는 약 1GB 입니다.| 상태 | 파일 구성 | 설명 |
|---|---|---|
| OPTIMIZE 전 | 1MB, 2MB, 500KB, 3MB, 100KB, 4MB | 6개의 작은 파일 |
| OPTIMIZE 후 | ~1GB | 1개의 최적화된 파일로 병합 |
기본 사용법
조건부 최적화
Optimized Write (자동 파일 크기 최적화)
OPTIMIZE를 수동으로 실행하는 대신, 데이터를 쓸 때 자동으로 적절한 크기의 파일을 생성 하는 기능도 있습니다.💡 Optimized Write 는 쓰기 시점에 파일 크기를 최적화하지만, 이미 쌓인 소형 파일은 처리하지 못합니다. 기존 파일의 압축에는 OPTIMIZE를 별도로 실행해야 합니다.
VACUUM (불필요한 파일 정리)
동작 원리
Delta Lake에서 UPDATE나 DELETE를 실행하면, 기존 파일은 즉시 삭제되지 않습니다. 타임 트래블과 진행 중인 쿼리를 위해 이전 버전의 파일이 보존 됩니다. VACUUM은 지정된 보존 기간보다 오래된 불필요한 파일을 영구적으로 삭제 합니다.기본 사용법
DRY RUN (삭제 미리 확인)
실제로 삭제하기 전에, 어떤 파일이 삭제될지 미리 확인할 수 있습니다.보존 기간 설정
⚠️ 주의사항:
- VACUUM 후에는 보존 기간 이전의 타임 트래블이 불가능 해집니다
- 기본 보존 기간 7일보다 짧게 설정하는 것은 강력히 권장하지 않습니다(진행 중인 쿼리가 실패할 수 있음)
- 7일 미만으로 설정하려면
spark.databricks.delta.retentionDurationCheck.enabled = false를 먼저 설정해야 합니다
ANALYZE TABLE (통계 수집)
💡 ANALYZE TABLE 은 테이블의 컬럼 통계(statistics) 를 수집하는 명령입니다. 쿼리 최적화기(Query Optimizer)가 이 통계를 활용하여 더 효율적인 실행 계획을 수립합니다.
사용법
수집되는 통계 정보
| 통계 | 설명 | 활용 |
|---|---|---|
| 행 수(numRows) | 테이블의 전체 행 수 | JOIN 순서 최적화 |
| 최소/최대값(min/max) | 각 컬럼의 최솟값과 최댓값 | Data Skipping |
| NULL 수(numNulls) | 각 컬럼의 NULL 개수 | 필터 최적화 |
| 고유값 수(distinctCount) | 컬럼의 고유값 수 | JOIN 전략 선택 |
운영 주기 권장사항
| 작업 | 권장 주기 | 설명 |
|---|---|---|
| OPTIMIZE | 일 1회 또는 데이터 변경 후 | 소형 파일을 합쳐 쿼리 성능 유지 |
| VACUUM | 주 1회 | 불필요한 파일 삭제로 스토리지 비용 절약 |
| ANALYZE TABLE | 주 1회 또는 대량 변경 후 | 쿼리 최적화기에 최신 통계 제공 |
운영 스크립트 예시
💡 Predictive Optimization 이 활성화된 Managed Table이라면, OPTIMIZE와 VACUUM을 Databricks가 자동으로 실행합니다. 수동 유지 보수가 필요 없어지므로, 가능하다면 Predictive Optimization 사용을 권장합니다. 자세한 내용은 Predictive Optimization 문서를 참고하세요.
현장에서 배운 것들: OPTIMIZE와 VACUUM의 현실
VACUUM을 안 해서 스토리지 비용이 3배로 뛴 사례
이건 제가 2022년에 실제로 마주한 상황입니다. 한 미디어 고객이 Databricks를 도입한 지 8개월째였는데, 월간 S3 비용이 계속 올라가서 원인 분석을 요청해왔습니다. 원인은 단순했습니다. VACUUM을 한 번도 실행하지 않았습니다.⚠️ 교훈: VACUUM은 “언젠가 해야지”가 아니라 Day 1부터 스케줄링 해야 합니다. Predictive Optimization이 있으면 자동이지만, 그렇지 않다면 주 1회 VACUUM을 반드시 스케줄에 넣으세요.
프로덕션에서 VACUUM DRY RUN을 먼저 돌려야 하는 이유
VACUUM은 되돌릴 수 없는 작업 입니다. 한번 삭제된 파일은 복구할 수 없습니다. 그래서 프로덕션에서는 반드시 DRY RUN을 먼저 실행해야 합니다. 실제로 한 고객이 DRY RUN 없이 VACUUM을 실행했다가 문제가 생긴 사례가 있습니다.OPTIMIZE 주기: 실전 가이드
“얼마나 자주 OPTIMIZE를 해야 하나요?”는 가장 많이 받는 질문입니다. 정답은 ”** 테이블의 쓰기 패턴에 따라 다르다**“입니다.| 쓰기 패턴 | OPTIMIZE 주기 | 이유 |
|---|---|---|
| Structured Streaming (1분 마이크로배치) | 1~4시간마다 | 매 배치마다 소형 파일 생성, 빠르게 누적 |
| 시간별 배치 적재 | 일 1회 (적재 후) | 적재 직후가 소형 파일이 가장 많은 시점 |
| 일 1회 배치 적재 | 적재 직후 1회 | 하루치 데이터가 이미 적절한 크기일 수 있으므로 확인 후 |
| 주 1회 대량 적재 | 적재 직후 1회 | 대량 적재 자체가 큰 파일을 생성할 수 있음 |
| 빈번한 MERGE (upsert) | 일 1~2회 | MERGE는 기존 파일을 재작성하므로 파편화 발생 |
OPTIMIZE가 정말 필요한지 확인하는 방법
무작정 OPTIMIZE를 실행하지 말고, 먼저 테이블 상태를 진단하세요.OPTIMIZE + VACUUM 자동화: 프로덕션 운영 패턴
수동으로 OPTIMIZE와 VACUUM을 실행하는 것은 초기에만 허용됩니다. 프로덕션에서는 반드시 자동화해야 합니다.패턴 1: Predictive Optimization (권장)
💡 Predictive Optimization이 하는 일: Databricks가 테이블의 쓰기 패턴, 쿼리 패턴, 파일 크기 분포를 자동으로 분석하여, 최적의 시점에 OPTIMIZE와 VACUUM을 실행합니다. 사람이 판단하는 것보다 정확하고, 잊지 않습니다. 가능하다면 이것을 1순위로 사용하세요.
패턴 2: Lakeflow Jobs로 스케줄링
많은 팀이 하는 실수들
| 실수 | 결과 | 올바른 방법 |
|---|---|---|
| OPTIMIZE 후 VACUUM을 안 함 | OPTIMIZE가 새 파일을 만들지만, 이전 소형 파일이 그대로 남아 스토리지 낭비 | OPTIMIZE → VACUUM 순서로 함께 실행 |
| VACUUM 보존 기간을 0으로 설정 | 진행 중인 쿼리 실패, 타임 트래블 완전 불가 | 최소 7일(168시간) 유지 |
| 피크 시간에 OPTIMIZE 실행 | 대량의 I/O로 다른 쿼리 성능 저하 | 트래픽이 적은 시간(새벽)에 실행 |
| 모든 테이블에 같은 주기 적용 | 쓰기가 적은 테이블에 불필요한 OPTIMIZE, 쓰기가 많은 테이블에 부족한 OPTIMIZE | 테이블별 쓰기 패턴에 따라 차등 적용 |
| WHERE 조건 없이 대형 테이블 OPTIMIZE | 전체 데이터 재작성으로 수 시간 소요 + 비용 폭증 | WHERE order_date >= current_date() - INTERVAL 7 DAYS 등 범위 지정 |
정리
| 명령어 | 목적 | 효과 |
|---|---|---|
| OPTIMIZE | 소형 파일 병합 | 쿼리 성능 향상 |
| VACUUM | 불필요한 파일 삭제 | 스토리지 비용 절약 |
| ANALYZE TABLE | 통계 정보 수집 | 쿼리 최적화기 성능 향상 |