비용 관리: storage lifecycle, compute sizing, query cost attribution
데이터 플랫폼 비용은 관리하지 않으면 반드시 증가한다
데이터 플랫폼은 규모가 커질수록 비용 문제가 먼저 터진다. 새 파이프라인을 추가할 때마다 스토리지와 컴퓨팅 요금이 올라가고, 어느 시점부터는 "누가 왜 이렇게 많이 쓰는지" 아무도 모르는 상태가 된다. 분기 클라우드 비용을 보고 나서야 움직이기 시작하면 이미 구조적 문제가 쌓여 있을 가능성이 높다.
데이터 플랫폼 엔지니어가 비용을 다루는 방식은 절약 캠페인이 아니다. 스토리지 생명주기 정책으로 데이터 온도에 맞는 계층을 자동으로 이동시키고, 컴퓨팅 자원을 실제 워크로드에 맞게 조정하며, 어떤 팀과 어떤 쿼리가 비용을 만드는지 추적해서 책임 단위를 나눈다. 이 세 가지가 없으면 비용 최적화는 일회성 정리에 그친다.
데이터 플랫폼 비용의 구성
대부분의 조직은 컴퓨팅 비용에 집중하지만 스토리지가 전체 비용의 30~40%를 차지하며 매달 자동으로 늘어난다. 네트워크 비용은 cross-region 데이터 이동, 분석 도구 egress, 대용량 export에서 예상치 못한 수준으로 나타나기도 한다. 숨은 비용은 attribution이 없으면 보이지 않아서 결국 "누군가 뭔가 많이 쓴다"는 형태로만 드러난다.
1. 스토리지 생명주기: 데이터 온도에 따라 계층을 나눈다
스토리지 비용 최적화의 핵심은 모든 데이터를 같은 계층에 두지 않는 것이다. 데이터는 생성 직후에는 자주 접근되다가 시간이 지나면 급격히 액세스 빈도가 떨어진다. 이 온도 차이를 인식하고 계층을 자동으로 이동시키는 것이 생명주기 정책이다.
스토리지 온도 계층
| 계층 | 특성 | 대표 스토리지 클래스 | 비용 수준 |
|---|---|---|---|
| Hot (빈번 접근) | 최근 30일, 매일 접근 | S3 Standard, GCS Standard | 높음 |
| Warm (간헐적 접근) | 30~90일, 월 단위 접근 | S3 Standard-IA, GCS Nearline | 중간 |
| Cold (희박 접근) | 90일~1년, 분기 단위 접근 | S3 Glacier Instant, GCS Coldline | 낮음 |
| Archive (보존 전용) | 1년 이상, 복구 드문 경우 | S3 Glacier Deep Archive, GCS Archive | 매우 낮음 |
AWS S3 기준으로 Standard-IA(Infrequent Access)는 Standard 대비 약 40% 저렴하고, Glacier Instant Retrieval은 약 68% 저렴하다. S3 Intelligent-Tiering은 액세스 패턴을 자동 분석해서 30일 접근 없으면 IA 계층으로, 90일 접근 없으면 Archive Instant 계층으로 이동시킨다. 단, 오브젝트 모니터링 비용(오브젝트당 $0.0025/월)이 있어서 소형 파일이 많으면 생명주기 비용이 오히려 늘 수 있다.
Lifecycle 정책의 실제 설계
스토리지 생명주기 정책은 시간을 트리거로 사용한다. 반면 Intelligent-Tiering은 실제 접근 패턴을 분석한다. 이 두 가지를 조합하는 것이 일반적이다.
Standard
Standard-IA
Glacier Instant
Deep Archive
2~3년 후
주의해야 할 점이 있다. Glacier 계층의 데이터는 복구 요청 후 즉시(Instant) 또는 수 시간(Standard/Bulk)이 걸린다. 데이터 복구 SLA가 있는 경우, Archive 계층으로 이동하기 전에 복구 시간을 운영 런북에 반영해야 한다. 또한 오브젝트 크기가 128 KB 미만인 경우 Intelligent-Tiering 모니터링 비용이 데이터 저장 절감분을 초과할 수 있으므로 소형 파일은 먼저 합쳐서 저장하는 것이 낫다.
데이터 만료와 삭제 정책
스토리지 생명주기에서 삭제 정책은 별도 설계가 필요하다. 규정 보존 요건(예: 회계 데이터 5년, 개인정보 처리 로그 3년)과 기술적 필요(예: backfill 가능한 raw 데이터 보존 기간)가 충돌할 수 있다. 이때는 보존 요건이 더 긴 쪽을 따르되, 어떤 경로로 삭제되는지 audit trail을 남겨야 한다.
| 데이터 유형 | 권장 보존 기간 | 삭제 전 체크 |
|---|---|---|
| raw event log | 최소 90일, 보통 1년 | backfill 가능 기간과 일치시킴 |
| staging / temp | 최대 7일 | 실패 run의 orphan 파일 포함 |
| mart snapshot | 6개월~2년 | time travel 필요 기간에 맞춤 |
| CDC binlog / WAL | 7~30일 | 복제 lag SLA의 3~5배 |
| 개인정보 포함 데이터 | 보존 요건 이후 즉시 | 별도 삭제 확인 프로세스 |
2. 컴퓨팅 규모 조정: 과소가 위험하고 과다는 낭비다
컴퓨팅 비용은 클러스터 크기와 실행 시간의 곱이다. 너무 작으면 쿼리가 느려지거나 OOM으로 실패하고, 너무 크면 idle 상태로 비용이 낭비된다. 적절한 크기를 찾는 것이 컴퓨팅 관리의 핵심이다.
Spark / 배치 컴퓨팅 규모 조정
Spark 클러스터에서 크기를 결정하는 핵심 요소는 executor 수(병렬성), executor 메모리(데이터 in-memory 처리 가능 크기), executor 코어(동시 task 수)다.
| 상황 | 증상 | 조정 방향 |
|---|---|---|
| 메모리 부족 | GC 압박, spill to disk, OOM | executor memory 증가 또는 파티션 수 증가 |
| 병렬성 낮음 | 일부 executor만 바쁘고 나머지 idle | executor 수 감소 또는 파티션 재분배 |
| 네트워크 셔플 과다 | 셔플 I/O가 전체 시간의 40% 이상 | 파티셔닝 전략 재검토 |
| 클러스터 idle | 전체 실행 시간의 20% 이상 대기 | auto-termination 설정, 동시 작업 묶기 |
Auto-scaling이 있는 플랫폼(Databricks, AWS EMR)에서는 최소-최대 executor 범위를 설정하고 워크로드에 따라 동적으로 조정한다. 단, auto-scaling은 scale-out에 수 분이 걸리므로 짧은 burst 작업에는 오히려 overprovision이 낫다.
Warehouse 가상 웨어하우스 규모 조정
Snowflake, BigQuery, Redshift Serverless처럼 warehouse 기반 플랫폼은 Credit 또는 slot 단위로 과금된다. 주요 패턴은 다음과 같다.
- Snowflake: Virtual warehouse XS~4XL 중에서 쿼리 복잡도와 동시 사용자에 맞춰 선택한다. 자동 일시정지(
AUTO_SUSPEND = 60)를 설정해서 idle time을 0에 가깝게 줄인다. - BigQuery: on-demand는 쿼리 당 scanned byte 기준 과금이므로 partition pruning과 column projection이 직접 비용에 영향을 준다. Reservations(slot 예약) 모드는 정해진 slot 수를 고정 비용으로 쓰므로 쿼리가 많으면 유리하다.
- Redshift: 클러스터형은 인스턴스 시간 기준이므로 야간에 pause/resume으로 비용을 줄인다. Serverless는 RPU 단위로 자동 조정된다.
워크로드 스케줄링으로 컴퓨팅 시간 줄이기
배치 파이프라인을 낮 시간대에 집중시키면 peak 클러스터가 필요하고, 야간에 분산하면 같은 클러스터를 더 길게 쓸 수 있다. 급하지 않은 리포트 쿼리, historical backfill, 데이터 품질 검사를 오프-피크 시간으로 이동하면 expensive compute를 줄일 수 있다. 다만 downstream SLA가 있는 파이프라인은 실행 시간을 마음대로 바꿀 수 없으므로 스케줄 변경 전 의존성 파악이 선행되어야 한다.
3. Query cost attribution: 누가 얼마나 쓰는지 추적한다
비용 관리에서 가장 어려운 부분은 스토리지 계층을 정리하거나 클러스터를 줄이는 것이 아니다. 어떤 팀의 어떤 쿼리가 비용을 만드는지 파악하고, 그 정보를 가지고 대화하는 것이다. Attribution 없이는 "누군가 뭔가 많이 쓴다"는 느낌만 남고 구체적인 개선이 어렵다.
warehouse / Spark
user, job_id, duration, bytes
team, pipeline, env
credit/slot × unit price
팀별·파이프라인별
태깅 전략
클라우드 자원에 태그를 붙이는 것은 attribution의 기초다. 최소한 team, pipeline, env 세 가지를 일관되게 붙이는 것이 목표다.
- Snowflake:
QUERY_TAG를 세션에 설정하거나 쿼리 코멘트에 JSON을 넣으면 QUERY_HISTORY 뷰에서 필터링 가능하다. - BigQuery: job label을 설정하면 billing export에서 label별 비용 집계가 된다.
- Spark:
spark.app.name과 custom spark.conf에 태그를 넣으면 Spark UI와 이벤트 로그에서 확인 가능하다. - AWS: Cost Allocation Tag를 활성화하면 Cost Explorer에서 태그별 비용을 분석할 수 있다.
비용이 많이 드는 쿼리 패턴
Attribution 데이터를 분석하면 특정 패턴이 반복적으로 큰 비용을 만들고 있음을 발견한다.
| 패턴 | 문제 | 개선 방향 |
|---|---|---|
| 파티션 없이 대용량 테이블 full scan | 매 실행마다 수 TB 스캔 | 날짜 파티션 필터 강제, 뷰 제한 |
| 동일 비용이 매일 반복되는 무거운 쿼리 | 집계 결과를 매번 재계산 | Materialized View 또는 pre-aggregate 적용 |
| 개발/테스트 쿼리가 프로덕션 클러스터에서 실행 | dev/prod 격리 없음 | 별도 dev warehouse, limit 강제 |
| 대용량 결과를 클라이언트로 export | 네트워크 비용과 메모리 압박 | 서버사이드 집계 후 export, row limit alert |
| 불필요한 중간 테이블이 장기 누적 | staging 데이터 orphan | lifecycle 정책, 정기 cleanup DAG |
Showback vs. Chargeback
비용 attribution은 두 가지 모델로 운영된다.
- Showback: 각 팀에 "당신 팀이 이만큼 썼다"는 정보를 주되, 실제 청구는 하지 않는다. 비용 인식을 높이는 것이 목적이다.
- Chargeback: 부서나 팀에 실제 비용을 분배한다. 비용 책임을 부여하는 대신 팀마다 자체 최적화 동기가 생긴다.
대부분의 조직은 showback으로 시작해서 비용 인식이 생기면 chargeback으로 전환한다. 어떤 모델이든 attribution 데이터가 정확하지 않으면 불신이 생기므로, 먼저 주요 파이프라인 10~20개에서 태깅 커버리지를 90% 이상으로 높이는 것이 우선이다.
4. 비용 관리 대시보드: 무엇을 봐야 하는가
비용 이상 징후는 일반적으로 점진적으로 증가하다가 어느 달에 갑자기 크게 보인다. 대시보드는 이 증가 추세를 조기에 잡는 것이 목적이다.
| 지표 | 의미 | 알림 기준 |
|---|---|---|
| 일일 스토리지 증가량 (TB) | 무계획 데이터 적재 탐지 | 7일 이동 평균 대비 20% 초과 |
| 팀별 compute credit | 이상 사용자·파이프라인 탐지 | 주간 비교 50% 이상 증가 |
| idle cluster time (%) | 낭비 컴퓨팅 탐지 | 20% 이상 idle 지속 |
| 상위 10 비용 쿼리 | 반복 최적화 대상 | 매주 리뷰 |
| orphan staging size (GB) | 미정리 임시 데이터 | 100GB 초과 지속 |
| 예상 월말 비용 | 예산 초과 예방 | 예산의 80% 도달 시 알림 |
Snowflake에서는 SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY, METERING_HISTORY 뷰를 이용해 쿼리별 크레딧 소비를 파악할 수 있다. BigQuery는 INFORMATION_SCHEMA.JOBS_BY_ORGANIZATION에서 byte processed, total_slot_ms를 팀별로 집계할 수 있다.
5. FinOps 사이클: 발견 → 최적화 → 검증 → 반복
비용 최적화는 일회성 작업이 아니다. 새로운 파이프라인이 추가되고, 팀이 성장하고, 데이터 볼륨이 늘어나면서 지속적으로 drift가 생긴다. FinOps 사이클은 이 drift를 정기적으로 잡는 루틴이다.
- Inform: 비용을 팀별, 파이프라인별, 리소스별로 attribution한다.
- Optimize: 생명주기 정책 갱신, idle 클러스터 정리, 비용 상위 쿼리 튜닝, orphan 데이터 삭제.
- Operate: 알림 임계값 조정, 새 프로젝트 온보딩 시 태깅 의무화, 주간 비용 리뷰.
- Repeat: 분기별 lifecycle 정책 검토, 반기별 compute sizing 재검토.
성숙한 조직은 새 파이프라인 온보딩 시 태깅 규칙, 예상 daily cost, auto-termination 설정을 change ticket에 포함하도록 표준화한다. 이렇게 하면 비용 이상이 생겼을 때 원인을 추적하는 비용이 크게 줄어든다.
마무리: 비용은 설계 시 결정된다
데이터 플랫폼 비용은 대부분 데이터를 적재하고 파이프라인을 구성할 때 결정된다. 모든 raw 데이터를 hot 스토리지에 영구 보관하거나, 분석 쿼리가 파티션 없이 대용량 테이블을 매일 full scan하는 구조라면, 아무리 클러스터를 줄여도 비용은 계속 오른다.
운영자가 해야 할 일은 어디서 비용이 나오는지 보이게 만드는 것이다. 스토리지 생명주기 정책은 데이터 온도에 맞는 계층을 자동으로 유지하고, 컴퓨팅 sizing은 워크로드 실측치로 조정하며, attribution은 팀이 자신의 사용량을 직접 보고 개선 동기를 갖게 한다. 이 세 가지가 갖춰지면 비용 대화가 "우리가 이번 달 너무 많이 쓴 것 같다"에서 "어떤 팀의 어떤 파이프라인을 어떻게 개선하면 얼마가 줄어든다"로 바뀐다.
References
- Amazon Web Services, "Amazon S3 Intelligent-Tiering," https://aws.amazon.com/s3/storage-classes/intelligent-tiering/
- Amazon Web Services, "Automate S3 Lifecycle rules at scale to transition data to S3 Intelligent-Tiering," https://aws.amazon.com/blogs/storage/automate-s3-lifecycle-rules-at-scale-to-transition-data-to-s3-intelligent-tiering/
- Databricks, "Best practices for cost optimization," https://docs.databricks.com/aws/en/lakehouse-architecture/cost-optimization/best-practices
- Snowflake, "Cost Optimization Well-Architected Framework," https://www.snowflake.com/en/developers/guides/well-architected-framework-cost-optimization-and-finops/
- Revefi, "5 Key Strategies for Cloud Cost Optimization," https://www.revefi.com/blog/cloud-data-cost-optimization
- Coalesce, "Data Platform Cost Optimization: A Playbook for Data Leaders," https://coalesce.io/data-insights/data-platform-cost-optimization-a-playbook-for-data-leaders/