CertNote/ 출퇴근 학습 노트
로드맵
KOEN
CLF-C02 · FoundationalCloud Practitioner - Foundational
DVA-C02 · AssociateDeveloper - Associate
SAA-C03 · AssociateSolutions Architect - Associate
SOA-C02 · AssociateCloudOps Engineer - Associate
SAP-C02 · ProfessionalSolutions Architect - Professional
DOP-C02 · ProfessionalDevOps Engineer - Professional
SCS-C03 · SpecialtySecurity - Specialty
MLA-C01 · AssociateMachine Learning Engineer - Associate
AIF-C01 · FoundationalAI Practitioner - Foundational
DEA-C01 · AssociateData Engineer - Associate
  • Week 1
    • 1.데이터 엔지니어링이란
    • 2.배치 vs 스트리밍
    • 3.AWS 데이터 서비스 조감도
    • 4.데이터 포맷과 모델링
    • 5.Week 1 종합 복습
  • Week 2
  • Week 3
  • Week 4
  • Week 5
    • 1.Amazon EMR: Spark·Hive와 클러스터 운영, 그리고 EMR Serverless
    • 2.Lambda 변환과 경량 처리: 이벤트 기반 ETL의 한계와 적합성
    • 3.오케스트레이션: Step Functions·MWAA·Glue Workflows의 선택 기준
    • 4.성능·비용 최적화: 파일 포맷·압축·파티셔닝과 작은 파일 문제
    • 5.Week 5 종합: 데이터 변환 2 — 엔진·오케스트레이션·최적화 통합 복습
  • Week 6
  • Week 7
  • Week 8
  • Week 9
  • Week 10
MLS-C01 · SpecialtyMachine Learning - Specialty
합격 후기

© CertNote · 주간랩스

  • 소개
  • 수정 기록
  • 문의
  • 이용약관
  • 개인정보처리방침
← DEA-C01/Week 5/Day 4

기준: DEA-C01 시험 가이드·오류 제보

DEA-C01· AssociateWeek 5 · Day 4읽기 약 10분

Day 4 - 성능·비용 최적화: 파일 포맷·압축·파티셔닝과 작은 파일 문제

데이터 엔지니어링에서 "느리다"와 "비싸다"는 대부분 같은 원인에서 나온다 — 불필요하게 많은 데이터를 읽기 때문이다. Athena, Redshift Spectrum, EMR, Glue는 모두 S3에서 읽은 데이터 양에 비례해 시간과 돈을 쓴다. 따라서 최적화의 본질은 단순하다: 읽어야 할 데이터를 최소화하는 것. 오늘은 그 네 가지 무기 — 파일 포맷, 압축, 파티셔닝, 파일 크기 — 를 다룬다. DEA-C01 시험 범위에 드는 영역이다.

행 기반 vs 열 기반: 가장 중요한 한 가지 결정

파일 포맷은 크게 두 부류다.

분류포맷저장 방식
행 기반(row)CSV, JSON, Avro한 행의 모든 컬럼을 연속 저장
열 기반(columnar)Parquet, ORC같은 컬럼의 값들을 연속 저장

분석 쿼리는 보통 "수백 컬럼 중 몇 개"만 본다. SELECT region, SUM(amount)는 region과 amount 두 컬럼만 필요하다. 행 기반 포맷은 한 행을 통째로 저장하므로, 두 컬럼만 원해도 모든 컬럼을 읽어야 한다. 반면 열 기반(Parquet/ORC)은 필요한 컬럼만 골라 읽는다(column pruning). 100개 컬럼 중 2개만 읽으면 I/O가 50배 줄 수 있다.

-- Athena: Parquet으로 저장된 테이블에서 두 컬럼만 조회
-- → region, amount 컬럼 블록만 S3에서 읽어 스캔량 최소화
SELECT region, SUM(amount) AS total
FROM sales_parquet
WHERE year = 2026
GROUP BY region;

💡 관련 이론: 열 기반 저장이 분석에서 빠른 이유는 I/O 절감뿐 아니라 압축 효율에도 있다. 같은 컬럼 값들은 데이터 타입과 분포가 비슷해(예: region 컬럼은 같은 문자열이 반복) 런-렝스 인코딩, 딕셔너리 인코딩 같은 기법이 극적으로 잘 먹힌다. 또 Parquet/ORC는 데이터 블록마다 min/max 통계를 메타데이터에 담아, 쿼리 조건에 맞지 않는 블록 전체를 읽지 않고 건너뛴다(predicate pushdown). 이 세 가지(컬럼 프루닝·고압축·통계 기반 스킵)가 열 포맷의 삼위일체다.

Parquet vs ORC vs Avro

세 포맷의 용도는 다음과 같이 구분된다.

포맷유형강점대표 용도
Parquet열 기반Spark/Athena 생태계 표준, 폭넓은 호환분석 쿼리 일반
ORC열 기반Hive 생태계 최적, 강한 압축·인덱스Hive/EMR 중심
Avro행 기반스키마 진화, 쓰기 빠름스트리밍 적재·스키마 변경 잦은 경우

시험 기준 직관: 분석 쿼리 최적화 = Parquet(또는 ORC), 스키마가 자주 바뀌는 행 단위 쓰기/스트리밍 = Avro. Athena·Redshift Spectrum·Glue가 Parquet을 가장 잘 다루므로, "비용 절감을 위한 포맷 선택"이 나오면 보통 Parquet이 정답이다.

⚠️ 함정: "Avro도 압축되는데 왜 분석엔 Parquet인가?"에서 헷갈린다. Avro는 행 기반이라 컬럼 프루닝이 안 된다 — 두 컬럼만 원해도 전체 행을 읽는다. Avro의 강점은 분석 속도가 아니라 스키마 진화(필드 추가/삭제를 안전하게 처리)와 빠른 쓰기다. 분석 스캔 비용 절감 문제에 Avro를 고르면 틀린다.

압축: 읽을 바이트를 줄이는 직접적 수단

압축은 S3 저장 비용과 스캔 비용을 동시에 줄인다. 압축 코덱 선택의 핵심은 분할 가능성(splittable)이다.

코덱압축률속도분할 가능
Snappy중간빠름(Parquet/ORC 내부에서) 예
Gzip높음느림단독 텍스트에서는 아니오
Zstd높음빠름예
Bzip2매우 높음매우 느림예
LZO낮음빠름예(인덱스 시)

분할 가능성이 왜 중요한가? 분산 엔진(Spark/Hive)은 큰 파일을 여러 워커가 나눠 병렬로 읽는다. 분할 불가능한 코덱(단독 Gzip 텍스트)은 파일 하나를 워커 하나가 통째로 읽어야 해서 병렬성을 죽인다. 그래서 거대한 단일 Gzip CSV는 최악의 조합이다.

실무 정석은 Parquet + Snappy다. Parquet 내부의 컬럼 청크 단위로 Snappy가 적용되며, 파일 자체는 블록 단위로 분할 가능해 병렬성과 압축을 모두 얻는다. 압축률을 더 원하면 Zstd가 좋은 현대적 대안이다.

파티셔닝: 안 읽을 데이터를 통째로 건너뛰기

파티셔닝(partitioning)은 데이터를 컬럼 값 기준 디렉터리로 물리적으로 분할 저장하는 것이다. 가장 흔한 것은 날짜 파티션이다.

s3://bucket/sales/
  year=2026/month=06/day=25/part-0001.parquet
  year=2026/month=06/day=26/part-0001.parquet

WHERE year=2026 AND month=06 AND day=26로 쿼리하면, 엔진은 해당 디렉터리만 읽고 나머지 날짜는 아예 열어보지도 않는다(partition pruning). 컬럼 프루닝이 "가로(컬럼) 방향" 절감이라면, 파티션 프루닝은 "세로(행) 방향" 절감이다.

-- 파티션 컬럼으로 필터 → 6월 26일 디렉터리만 스캔, 나머지 날짜 스킵
SELECT product_id, SUM(amount)
FROM sales
WHERE year = 2026 AND month = 6 AND day = 26
GROUP BY product_id;

파티션 키는 쿼리에서 자주 필터하는 저(低)카디널리티 컬럼이어야 한다(날짜, 지역 등). 반대로 고카디널리티 컬럼(user_id 같은 수백만 값)으로 파티셔닝하면 과도한 파티션이 생겨 오히려 메타데이터 폭증과 작은 파일 문제를 일으킨다.

🎯 시나리오: Athena 비용이 폭증한 팀이 있다. 데이터는 거대한 단일 Gzip CSV로 S3에 쌓여 있고, 쿼리는 대부분 최근 7일·특정 지역만 본다. 최적화 처방은 (1) 포맷을 Parquet+Snappy로 변환(컬럼 프루닝+압축), (2) year/month/day로 파티셔닝(파티션 프루닝으로 날짜 범위 스킵), (3) 자주 쓰는 region을 보조 파티션 또는 정렬 키로, (4) 작은 파일은 적정 크기로 compaction. 이 조합으로 스캔량이 수십~수백 배 줄어 Athena 비용이 급감한다. Glue ETL 작업으로 CSV→Parquet 변환과 파티셔닝을 일괄 수행한다.

작은 파일 문제: 조용한 성능 킬러

S3에 작은 파일이 수만 개 쌓이면, 데이터 총량이 작아도 쿼리가 극단적으로 느려진다. 이유는 파일마다 오버헤드가 붙기 때문이다 — 각 파일은 S3 LIST/GET 요청, 메타데이터 파싱, 태스크 스케줄링 비용을 일으킨다. 1KB 파일 10만 개는 1GB 파일 하나보다 압도적으로 느리고 비싸다.

작은 파일은 어디서 생기나?

  • 스트리밍 적재(Kinesis/Firehose)가 짧은 버퍼 주기로 잦은 작은 파일 생성
  • Spark가 과도한 파티션(repartition)으로 작은 출력 다수 생성
  • 고카디널리티 파티셔닝으로 파티션당 데이터가 잘게 쪼개짐

해결책은 컴팩션(compaction) — 작은 파일들을 큰 파일로 병합하는 것이다.

# Spark: 출력 파티션 수를 줄여 작은 파일을 큰 파일로 통합
(df
  .repartition(8)          # 또는 coalesce로 출력 파일 수 제어
  .write
  .mode("overwrite")
  .parquet("s3://curated/sales/"))

AWS는 자동 도구도 제공한다. Firehose의 버퍼 크기/간격을 키워 더 큰 파일로 적재하고, Glue의 작은 파일 그룹화(groupFiles/groupSize)나 테이블 포맷의 자동 컴팩션을 활용한다.

적정 파일 크기는 보통 128MB~1GB 범위가 권장된다. 너무 크면(수 GB+) 분할·병렬성이 떨어지고 일부 워커만 일하며, 너무 작으면 오버헤드가 지배한다. 128MB는 우연이 아니라 HDFS의 기본 블록 크기에서 유래했다 — 하나의 블록이 하나의 처리 단위(태스크)에 대응하도록 설계된 값이다. Iceberg·Hudi·Delta 같은 오픈 테이블 포맷은 자동 컴팩션과 파일 크기 관리를 내장해 이 문제를 구조적으로 완화한다.

최적화 우선순위 정리

성능·비용 문제를 만났을 때의 점검 순서:

  1. 포맷: 텍스트(CSV/JSON) → 열 기반(Parquet/ORC)으로 전환했는가?
  2. 압축: 분할 가능한 코덱(Snappy/Zstd)을 쓰는가? 거대 단일 Gzip은 없는가?
  3. 파티셔닝: 자주 필터하는 저카디널리티 컬럼으로 파티션해 프루닝되는가?
  4. 파일 크기: 작은 파일을 128MB~1GB로 컴팩션했는가?

이 네 가지가 Athena 스캔 비용, Redshift Spectrum 비용, EMR/Glue 처리 시간을 모두 좌우한다.

정리

성능·비용 최적화는 "읽을 데이터 최소화"로 요약된다. 열 기반 포맷(Parquet)은 컬럼 프루닝과 통계 기반 스킵으로 가로 방향을 줄이고, 파티셔닝은 안 읽을 디렉터리를 통째로 건너뛰어 세로 방향을 줄인다. 압축은 분할 가능한 코덱(Snappy/Zstd)을 골라 병렬성과 절감을 동시에 얻고, 작은 파일은 컴팩션으로 오버헤드를 없앤다. 거대 단일 Gzip CSV가 최악, Parquet+Snappy+날짜 파티셔닝+적정 파일 크기가 정석이다. 내일은 Week 5 전체를 종합 복습한다.

📝 연습 문제

선택지를 클릭하면 정답·해설이 펼쳐집니다.

문제 1

Athena 쿼리가 대부분 100개 컬럼 중 3~4개만 조회하는데 데이터가 CSV로 저장돼 비용이 높다. 스캔 비용을 가장 효과적으로 줄이는 포맷 전환은?

문제 2

거대한 단일 Gzip 압축 CSV 파일을 EMR Spark가 처리하는데 병렬성이 전혀 나오지 않고 워커 하나만 일한다. 근본 원인은?

문제 3

매출 데이터를 year/month/day로 파티셔닝해 S3에 저장했다. WHERE year=2026 AND month=6 AND day=26 쿼리가 빠르고 저렴한 이유는?

문제 4

스트리밍 적재로 S3에 1~10KB짜리 파일이 하루 수십만 개씩 쌓이면서 쿼리가 점점 느려진다. 데이터 총량은 크지 않다. 가장 적절한 대응은?

문제 5

스키마(필드)가 자주 추가·변경되고 행 단위로 빠르게 쓰는 스트리밍 적재 단계에 가장 적합한 포맷은?

이전오케스트레이션: Step Functions·MWAA·Glue Workflows의 선택 기준Week 5 · Day 3다음 Week 5 종합: 데이터 변환 2 — 엔진·오케스트레이션·최적화 통합 복습Week 5 · Day 5

참고 공식 자료

  • DEA-C01 공식 시험 안내(새 탭에서 열림)
  • Amazon S3 공식 문서(새 탭에서 열림)
  • Amazon Athena 공식 문서(새 탭에서 열림)
  • AWS Glue 공식 문서(새 탭에서 열림)
  • Amazon Data Firehose 공식 문서(새 탭에서 열림)
  • Amazon EMR 공식 문서(새 탭에서 열림)

이 페이지

  • 행 기반 vs 열 기반: 가장 중요한 한 가지 결정
  • Parquet vs ORC vs Avro
  • 압축: 읽을 바이트를 줄이는 직접적 수단
  • 파티셔닝: 안 읽을 데이터를 통째로 건너뛰기
  • 작은 파일 문제: 조용한 성능 킬러
  • 최적화 우선순위 정리
  • 정리
  • 연습 문제