데이터 파이프라인은 잘 돌아가도 비용이 통제되지 않으면 지속할 수 없다. 비용을 줄이려면 먼저 "무엇이 얼마를 쓰는가"를 봐야 한다.
비용 할당 태그(Cost Allocation Tags) 는 두 종류다. AWS 가 붙여 주는 AWS 생성 태그(aws:createdBy 등)와 사용자가 다는 사용자 정의 태그(Project, Environment, Team)다.
두 종류 모두 Billing 콘솔에서 따로 활성화 해야 Cost Explorer 와 비용 보고서에 나타난다. 태그가 콘솔에 보이기까지 최대 24시간이 걸린다.
조직(Organizations)에서는 관리 계정 만 비용 할당 태그를 활성화할 수 있다. 멤버 계정의 엔지니어가 태그를 달아도 관리 계정이 활성화하지 않으면 비용에 반영되지 않는다.
태그 전략 예:
Project=orders-pipeline
Environment=prod
CostCenter=data-eng
→ Cost Explorer 에서 "data-eng 가 prod 의 orders-pipeline 에 쓴 비용"으로 분해
💡 관련 이론 : 비용 할당 태그는 오랫동안 "활성화한 시점 이후의 비용에만 적용되고 소급되지 않는다"고 알려졌고 시험 자료에도 그렇게 나올 수 있다. 현행 문서에는 관리 계정이 최대 12개월까지 백필(backfill) 을 요청하는 기능이 있다. 다만 백필은 활성화 상태를 과거로 넓힐 뿐이어서, 그 기간에 리소스에 태그가 실제로 달려 있지 않았다면 값은 채워지지 않는다. 태그 정책을 초기에 정해 일관되게 다는 것이 여전히 답이다.
도구 시점 하는 일 고르는 단서 Cost Explorer 사후 서비스·태그·기간별 비용 추세 시각화와 예측 "어디에 얼마를 썼는지 분석" AWS Budgets 사전 설정 정해 둔 예산·임계값에 닿으면 알림 또는 액션 "월 예산의 80% 에 도달하면 알림" Cost Anomaly Detection 상시 ML 로 평소 패턴을 학습해 비정상 급증을 통보 "임계값을 모르는 예상 밖 급증" Compute Optimizer 주기적 리소스 사이징 권고 "인스턴스가 과하게 큰지"
Budgets 는 내가 정한 숫자를 넘을 때만 운다. 평소 월 100 을 쓰던 팀이 300 을 쓰게 돼도 예산이 500 이면 조용하다. 그 구간을 잡는 것이 Anomaly Detection 이다.
서비스 과금 단위 비용을 좌우하는 노브 Glue ETL DPU × 실행 시간 워커 타입·수, 실행 시간, Flex EMR on EC2 인스턴스 시간(EC2 요금 + EMR 요금) 인스턴스 타입·수, 스팟 비중, 유휴 시간 Lambda 요청 수 + 메모리 × 실행 시간 메모리 설정, 실행 시간 Athena 스캔한 데이터량 포맷·압축·파티션, 워크그룹 한도 Redshift 프로비저닝 노드 시간 노드 타입·수, 일시 중지 Redshift Serverless RPU × 사용 시간 기본 용량, 사용 한도 Kinesis Data Streams 프로비저닝은 샤드 시간, 온디맨드는 데이터량 샤드 수, 용량 모드 S3 저장량 + 요청 수 + 전송량 스토리지 클래스, 파일 개수, 수명 주기 Step Functions 표준 상태 전이 수 재시도 횟수, 루프 구조
과금 단위가 "시간"인 서비스는 유휴 시간 이 낭비이고, "데이터량"인 서비스는 불필요하게 읽은 바이트 가 낭비다. 문제의 서비스가 어느 쪽인지 보면 답의 방향이 정해진다.
DPU 하나는 vCPU 4개와 메모리 16GB 에 해당하는 상대 단위다.
워커 타입 워커당 DPU vCPU / 메모리 맞는 워크로드 G.025X 0.25 2 / 4GB 소량 스트리밍 잡 전용 G.1X 1 4 / 16GB 대부분의 변환·조인 G.2X 2 8 / 32GB 대부분의 변환·조인(메모리가 더 필요할 때) G.4X / G.8X 4 / 8 16 / 64GB, 32 / 128GB 가장 무거운 변환·집계·조인 G.12X / G.16X 12 / 16 48 / 192GB, 64 / 256GB 초대형 워크로드 R.1X ~ R.8X 1 ~ 8 메모리 최적화 구성 OOM 이 잦은 메모리 집약 잡
기존 자료에 나오는 Standard 워커 타입은 Glue 1.0 이하의 옛 구성 이다. 2.0 이상은 워커 타입과 워커 수로 지정하며, Standard 는 Auto Scaling 도 지원하지 않는다.
Spark 가 필요 없는 작은 작업은 Python shell 잡 (0.0625 DPU 또는 1 DPU)이 훨씬 싸다. 파일 몇 개 옮기고 API 한 번 부르는 일에 Spark 클러스터를 띄우지 않는다.
Flex 실행 클래스 는 급하지 않은 잡(테스트, 일회성 적재, 야간 배치)에 쓴다. 시작이 늦어질 수 있는 대신 싸다. Glue 3.0 이상, G.1X·G.2X 에서만 된다.
Auto Scaling (--enable-auto-scaling)은 Glue 3.0 이상에서 스테이지·마이크로배치의 병렬도에 따라 워커를 넣고 뺀다. 이때 지정한 워커 수는 "고정 수"가 아니라 상한 이 된다.
잡은 실행 시간으로 과금되므로 타임아웃 이 비용 안전장치다. 멈춰 버린 잡이 기본 타임아웃까지 돌면 그 시간이 전부 청구된다.
# Auto Scaling 을 켜고 최대 20 워커로 실행
aws glue start-job-run \
--job-name orders-transform \
--worker-type G.2X --number-of-workers 20 \
--arguments '{"--enable-auto-scaling":"true"}'
사이징 근거는 Day 1 의 두 지표다. numberMaxNeededExecutors(필요한 수)가 numberAllExecutors(실제 수)를 계속 웃돌면 워커가 부족하고, 한참 밑돌면 과하다.
과소 프로비저닝: OOM·스로틀·지연 → SLA 위반
과대 프로비저닝: 유휴 리소스 → 낭비
목표: 워크로드 프로파일에 맞춘 베이스라인 + 변동분은 자동 스케일링
노드 역할 구매 옵션 프라이머리 클러스터 조율 온디맨드(끊기면 클러스터가 죽는다) 코어 태스크 실행 + HDFS 데이터 보관 온디맨드 또는 약정 태스크 태스크 실행만, 데이터 보관 없음 스팟
Managed Scaling 은 EMR 이 클러스터 지표를 보고 코어·태스크 노드를 자동으로 늘리고 줄인다. 사용자는 한계만 정한다.
파라미터 의미 MinimumCapacityUnits / MaximumCapacityUnits클러스터 용량의 하한·상한(프라이머리 노드는 대상 아님) MaximumOnDemandCapacityUnits온디맨드로 채울 수 있는 상한. 넘는 부분은 스팟으로 채운다 MaximumCoreCapacityUnits코어 노드의 상한. 넘는 부분은 태스크 노드로 채운다
{
"ComputeLimits" : {
"UnitType" : "Instances" ,
"MinimumCapacityUnits" : 2 ,
"MaximumCapacityUnits" : 100 ,
"MaximumOnDemandCapacityUnits" : 10 ,
"MaximumCoreCapacityUnits" : 17
}
}
위 설정은 "인스턴스 100대까지, 그중 온디맨드는 10대까지, 코어는 17대까지"다. 나머지는 스팟 태스크 노드로 늘어난다.
Managed Scaling 은 YARN 기반 애플리케이션 (Spark, Hadoop, Hive, Flink)에서만 동작한다. Presto·HBase 처럼 YARN 을 쓰지 않는 워크로드는 대상이 아니다.
Spark 의 동적 리소스 할당을 끄면 Managed Scaling 이 필요 이상으로(최대치까지) 늘릴 수 있다. 기본값인 켜진 상태로 둔다.
스팟은 크게 싸지만 회수될 수 있다. 코어 노드를 스팟으로 두면 회수 때 HDFS 데이터가 함께 사라진다. 데이터를 S3 에 두고(EMRFS) 클러스터를 일시적으로 쓰면 이 위험과 유휴 비용이 함께 줄어든다.
일이 끝난 클러스터가 켜져 있는 것이 EMR 최대의 낭비다. 자동 종료 정책이나 스텝 완료 후 종료 설정을 쓴다.
기능 흡수하는 변동 동작 주의점 Redshift Concurrency Scaling 동시 쿼리 폭증 WLM 큐의 Concurrency Scaling 모드를 auto 로 두면 대기할 쿼리를 임시 클러스터로 보낸다 실제 쿼리를 돌린 시간만 과금. 쓰기 작업은 RA3·RG 노드에서만 지원 Redshift Serverless 사용량 전반 쿼리가 있을 때만 RPU 를 쓴다 간헐적 워크로드에 유리 Kinesis 온디맨드 유입량 변동 샤드를 서비스가 관리 트래픽이 일정하면 프로비저닝이 싸다 Glue Auto Scaling 스테이지별 병렬도 차이 워커를 실행 중 증감 상한은 직접 정한다 EMR Managed Scaling YARN 대기량 코어·태스크 노드 증감 YARN 애플리케이션만
Concurrency Scaling 클러스터의 기본 개수는 1 이고 max_concurrency_scaling_clusters 로 조절한다. 메인 클러스터 사용에 따라 무료 크레딧이 쌓이므로 짧은 피크는 추가 비용 없이 넘어갈 수 있다.
Concurrency Scaling 은 대기열 을 줄이는 기능이지 느린 쿼리를 빠르게 하는 기능이 아니다. 쿼리 하나가 느리면 분산 키·정렬 키·노드 사양 문제다.
Lambda 는 메모리 설정이 CPU 할당도 함께 정한다. 메모리를 올려 실행 시간이 줄면 총비용이 오히려 내려가는 구간이 있다. 여러 메모리 값으로 실측해 고른다.
💡 관련 이론 : 자동 스케일링은 "변동"을 흡수할 뿐 "잘못된 베이스라인"을 고치지 못한다. 평소 비용이 높다면 스케일링 상한을 만질 것이 아니라 베이스라인 사이징을 다시 잡는다. 순서는 항상 사이징 → 스케일링이다.
옵션 맞는 사용량 데이터 파이프라인에서의 자리 온디맨드 예측 불가·단기 새 워크로드, 프라이머리·코어 노드 Savings Plans / 예약 예측 가능한 베이스라인 상시 가동 클러스터, 프로비저닝 Redshift 스팟 중단을 견디는 작업 EMR 태스크 노드, 재실행 가능한 배치
Athena 워크그룹의 쿼리당 한도 : 쿼리 하나가 스캔할 수 있는 양의 상한이다. 넘으면 쿼리가 취소 되고, 취소되기 전까지 스캔한 만큼은 과금된다. 최솟값은 10MB 이고 워크그룹당 하나만 둔다.
워크그룹 전체 사용량 알림 : 일정 기간의 누적 스캔량이 임계값을 넘으면 SNS 로 알린다. 이쪽은 쿼리를 자동으로 취소하지 않는다. 막으려면 알림을 받아 Lambda 로 워크그룹을 비활성화하는 식으로 직접 잇는다.
컬럼 포맷·압축·파티셔닝 : 스캔한 바이트로 과금되므로 Parquet + 압축 + 파티션 프루닝이 곧 비용 절감이다. SELECT * 는 컬럼 포맷의 이점을 버린다.
작은 파일 compaction : 파일이 많으면 요청 비용과 목록 조회·메타데이터 부담이 는다.
S3 수명 주기 : 오래된 raw 데이터를 저빈도·아카이브 클래스로 옮기고, 미완료 멀티파트 업로드를 정리한다. 자주 읽는 데이터를 아카이브로 보내면 꺼낼 때 비용과 시간이 든다.
-- 나쁜 예: 전체 컬럼, 파티션 조건 없음 → 테이블 전체 스캔
SELECT * FROM orders WHERE order_status = 'PAID' ;
-- 좋은 예: 필요한 컬럼만, 파티션 컬럼으로 범위 제한
SELECT order_id, amount FROM orders
WHERE dt BETWEEN '2026-06-01' AND '2026-06-07' AND order_status = 'PAID' ;
증상 원인 조치 Cost Explorer 에 태그가 안 보임 태그를 활성화하지 않음, 또는 관리 계정이 아님 관리 계정에서 활성화, 최대 24시간 대기 예산 안인데 비용이 평소의 몇 배 Budgets 임계값 미만의 급증 Cost Anomaly Detection Glue 비용이 데이터 양에 비해 큼 워커 과다, 멈춘 잡이 타임아웃까지 실행 익스큐터 지표로 재사이징, Auto Scaling, 타임아웃 단축 EMR 비용이 일이 없는 밤에도 발생 유휴 클러스터 자동 종료 정책, 일시적 클러스터 스팟 회수 때 잡이 처음부터 다시 코어 노드가 스팟 코어는 온디맨드, 태스크만 스팟 Redshift 대시보드가 아침마다 대기 동시성 부족 Concurrency Scaling Athena 비용 폭증 파티션 조건 없는 쿼리, 행 포맷 쿼리당 한도, Parquet·파티션 자동 스케일링을 켰는데도 평소 비용이 높음 베이스라인 과대 최소 용량·기본 사이징 재조정
지문 단서 정답 "프로젝트·환경별로 비용을 분해" 비용 할당 태그 활성화 + Cost Explorer "예상 밖의 비용 급증을 자동 탐지" Cost Anomaly Detection "예산의 일정 비율에 도달하면 알림" AWS Budgets "Glue 잡의 워커를 실행 중 자동 조절" Glue Auto Scaling "Spark 가 필요 없는 작은 스크립트를 싸게" Glue Python shell "급하지 않은 Glue 잡의 비용 절감" Flex 실행 클래스 "EMR 비용 절감 + 중단 내성" 코어 온디맨드, 태스크 스팟 "동시 쿼리 폭증 때만 용량 추가" Redshift Concurrency Scaling "분석가의 실수 쿼리가 수 TB 를 스캔" Athena 워크그룹 쿼리당 한도 "Athena·Spectrum 쿼리 비용 직접 절감" Parquet + 압축 + 파티션 프루닝
내일은 이번 주의 네 주제(모니터링·품질·트러블슈팅·비용)를 하나의 운영 흐름으로 묶어 복습한다.
비용 할당 태그 : 비용을 프로젝트·팀별로 나눠 보기 위해 리소스에 붙이고 Billing 에서 활성화하는 태그.
백필(backfill) : 태그의 활성화 상태를 과거 기간까지 넓혀 지난 비용 데이터에 반영하도록 요청하는 것.
DPU : Glue 의 처리 용량 단위. 하나가 vCPU 4개와 메모리 16GB 에 해당한다.
Flex 실행 클래스 : 시작이 늦어질 수 있는 대신 싼 Glue 잡 실행 방식.
Managed Scaling : EMR 이 지표를 보고 노드 수를 알아서 조절하는 기능. 한계만 정해 주면 된다.
코어 노드 / 태스크 노드 : 코어는 HDFS 데이터를 갖고, 태스크는 계산만 한다. 그래서 태스크만 스팟으로 돌린다.
Concurrency Scaling : Redshift 가 동시 쿼리가 몰릴 때 임시 클러스터를 붙여 대기열을 줄이는 기능.
스팟 인스턴스 : 남는 EC2 용량을 싸게 쓰되 AWS 가 필요하면 회수해 가는 구매 옵션.
워크그룹 : Athena 쿼리를 묶어 설정·한도·비용을 따로 관리하는 단위.
베이스라인 사이징 : 평상시 부하에 맞춘 기본 용량. 자동 스케일링보다 먼저 맞춰야 한다.
📝 연습 문제 선택지를 클릭하면 정답·해설이 펼쳐집니다.
데이터 팀이 프로젝트별·환경별 AWS 비용을 분해해서 보고 싶을 때 가장 먼저 해야 할 일은?
A 모든 리소스를 한 계정으로 통합 B 모든 인스턴스를 Spot으로 전환 C Cost Allocation Tags를 일관되게 달고 청구 콘솔에서 활성화 D CloudTrail 데이터 이벤트 활성화 Glue 잡 실행 중 스테이지별 필요량에 따라 워커 수를 동적으로 늘리고 줄여 비용과 성능을 모두 잡는 기능은?
A Glue Auto Scaling B Job Bookmark C Partition Projection D DynamicFrame EMR 클러스터에서 비용을 크게 절감하면서도 중단 가능성에 견디도록 구성하는 전형적 패턴은?
A 모든 노드를 Spot으로 구성 B 모든 노드를 On-Demand로 구성 C 코어 노드를 Spot, 태스크 노드를 On-Demand D 코어 노드는 On-Demand/약정, 태스크 노드는 Spot Athena와 Redshift Spectrum의 쿼리 비용을 직접적으로 줄이는 가장 효과적인 방법은?
A 모든 데이터를 CSV로 저장 B Parquet 컬럼 포맷 + 압축 + 파티션 프루닝으로 스캔 바이트 감소 C 쿼리를 더 자주 실행 D 결과를 항상 JSON으로 출력 AWS 비용에서 평소와 다른 비정상적인 급증을 머신러닝으로 자동 탐지하고 통보하는 서비스는?
A AWS Budgets B Trusted Advisor C Compute Optimizer D Cost Anomaly Detection