Spark 클러스터 규모 설정 방법, 그리고 하지 말아야 할 방법

발행: (2026년 3월 2일 오전 04:44 GMT+9)
15 분 소요
원문: Dev.to

I’m happy to translate the article for you, but I’ll need the full text of the post (the content you’d like translated). Could you please paste the article’s body here? I’ll keep the source line exactly as you provided and translate everything else while preserving the formatting, markdown, and code blocks.

Interview Question

You need to process 1 TB of data in Spark. How do you size the cluster?

Most interview answers start with a simple division:

1 TB → choose 128 MB partitions → ~8 000 partitions → map to cores → decide number of nodes

That approach is clean and logical, but it is also incomplete.
Cluster size is not derived from the raw data size alone; it is driven by the workload behavior.

1. “1 TB”는 실제로 무엇을 의미할까?

측면왜 중요한가
객체 스토리지의 압축 Parquet스토리지 효율성만 제공하고 실행 시 메모리 사용량은 제공하지 않는다.
파티션 프루닝필터에 따라 전체 디렉터리 파티션을 건너뛴다.
프레디케이트 푸시‑다운필터를 스토리지 계층으로 전달해 일치하는 행 그룹만 읽는다.
컬럼 프루닝필요한 컬럼만 읽는다.

예시: 날짜별 파티션이 된 1 TB 테이블은 단일 일 쿼리에서 150‑300 GB 스캔이 될 수 있다.
클러스터 크기 조정은 테이블 크기가 아니라 실제 스캔 크기를 기준으로 해야 한다.

2. 컬럼형 데이터의 런타임 확장

  • 디스크 상: Parquet는 압축 및 인코딩됨.
  • 메모리 상: 압축 해제, 디코딩, 그리고 Spark 내부 행 형식으로 물리화됨.

1 TB 압축 데이터셋은 처리 중에 실행기에서 2‑4 TB까지 부풀어 오를 수 있으며, 이는 다음에 영향을 미칩니다:

  • 실행기 메모리 크기 설정
  • 스필 발생 가능성
  • GC 압력
  • 메모리‑오버헤드 설정

Note: 디스크 크기는 메모리 기준이 되는 경우가 드물며, 메모리가 실제 기준이 됩니다.

3. Spark의 실행 모델

Spark는 단계들의 DAG를 실행하며, 단계들은 셔플에 의해 구분됩니다.
1 TB 작업은 다음과 같이 구성될 수 있습니다:

  1. 필터 → 400 GB
  2. 조인 및 확장 → 2.5 TB 셔플
  3. 집계 → 50 GB

Spark은 입력 크기에 관심을 두지 않고, 셔플, 정렬 또는 스필해야 하는 가장 큰 중간 상태에 관심을 가집니다.
조인이 2.5 TB까지 폭증한다면, 그것이 여러분의 규모 산정 기준이 됩니다.

4. 변동성 및 꼬리‑리스크

  • 안정적: 매일 1 TB?
  • 변동적: 평상시에는 800 GB, 분기 말에는 1.4 TB.

프로덕션 시스템은 평균이 아니라 95번째 백분위수 부하에서 실패한다.
평균이 아니라 꼬리를 기준으로 규모를 잡아라.

5. Spark’s design assumptions (and when they break)

가정실패 시 발생하는 현상
Data can be evenly partitionedSkew creates hot partitions → bottlenecks
Most transformations are narrowWide shuffles become expensive
Network is slower than CPUAdding cores to a network‑saturated node yields no benefit
Memory is finiteOOM, excessive spilling, GC pressure

When these assumptions hold, Spark scales predictably.
When they don’t, adding nodes does not fix the root cause.

6. 워크로드 중심 병목 현상 분류

6.1 CPU 바운드 (무거운 UDF, 암호화, 압축)

신호조치
CPU 사용률 높음, spill 적음, shuffle 대기 최소코어를 확장하고 컴퓨트 최적화 인스턴스 사용

6.2 Memory 바운드 (대규모 조인, 광범위 집계, 캐싱)

신호조치
spill 지표 높음, GC 시간 길음, executor OOMexecutor 메모리를 늘리거나 작업당 메모리 사용량 감소

6.3 I/O 바운드 (오브젝트 스토어 읽기, 작은 파일, 느린 디스크)

신호조치
CPU 사용률 낮음, 파일 열기 오버헤드 높음, 작업 역직렬화 시간 길음컴퓨팅 확장 전에 파일 레이아웃 및 압축 정리

6.4 Shuffle‑heavy

신호조치
shuffle‑read 가져오기 대기 높음, reduce 단계에서 CPU 낮음, executor가 원격 블록을 기다림노드당 네트워크 대역폭은 고정되어 있으므로, 포화된 노드에 코어를 추가해도 거의 도움이 되지 않음을 기억하세요.

7. 일반적인 “1 TB” 함정

  1. 셔플 배수 무시 – 셔플 양은 입력 크기의 **2‑3×**가 될 수 있다.
  2. 핫 키 – 단일 핫 키가 200 GB 파티션을 만들 수 있어, 하나의 executor가 병목이 된다.
  3. 스큐 – 데이터 분포가 고르지 않아 병렬성이 붕괴된다.

Spark UI에서 스큐 감지 방법

  • 최대 작업 시간중앙값을 비교한다.
  • 작업당 셔플 읽기 크기를 확인한다.
  • 데이터 양이 과도하게 많은 리듀서가 있는지 살펴본다.

한 작업이 다른 작업보다 10× 오래 실행되면 → 클러스터 규모가 아니라 분포 문제이다.

완화 전략

  • 핫 키에 소금(salting) 적용
  • 조인 전에 사전 집계 수행
  • 가능한 경우 브로드캐스트 조인 사용
  • 중간 정도 스큐에 대해 셔플 파티션 수 증가
  • 데이터 모델 재설계

8. Spill & 디스크 처리량

Shuffle 또는 정렬 중 실행 메모리가 가득 차면 Spark는 로컬 디스크에 spill하여 디스크 처리량이 새로운 병목 현상이 됩니다.

느린 로컬 디스크의 증상

  • 작업 실행 시간 증가
  • Executor 수명 연장
  • GC 압력 증가
  • 비선형 단계 지연

식별 방법

  • 높은 spill 지표
  • Shuffle 단계에서 작업 실행 시간 증가
  • GC 시간 증가

완화 방안

  • Executor 메모리 증가
  • 작업당 파티션 크기 감소
  • Shuffle 파티션 수 증가
  • 더 빠른 로컬 디스크 사용(NVMe)
  • 상위 단계에서 Shuffle footprint 감소

9. 데이터 레이아웃이 중요함

질문영향
1 TB는 어디에 저장되어 있나요?5개의 큰 Parquet 파일 vs. 800 k개의 작은 파일 vs. 올바르게 파티션된 데이터
데이터가 조인 키에 따라 클러스터링되어 있나요?셔플 비용에 크게 영향을 줍니다
  • 작은 파일 → 작업 스케줄링 오버헤드 증가, 파일 목록 조회 지연, 드라이버 압박.
  • 잘못된 파티션 → 스캔 크기 증가.
  • 잘못된 클러스터링 → 셔플 비용 증가.

Sometimes the correct answer is: Fix the data layout first.

Only after the data is well‑partitioned, compacted, and appropriately clustered does it make sense to talk about the number of nodes, cores, and memory per executor.

TL;DR Checklist

  1. 실제 스캔 크기 파악 (프루닝, 푸시‑다운, 컬럼 선택).
  2. 런타임 데이터 확장 추정 (2‑4× 압축 비율).
  3. 가장 큰 중간 상태 식별 (셔플, 조인, 집계).
  4. 병목 현상 분류 (CPU, 메모리, I/O, 셔플).
  5. 데이터 레이아웃 검증 (파일 크기, 파티셔닝, 클러스터링).
  6. 메모리 및 코어 규모 결정 – 1 TB 원시 데이터가 아니라 단계 1‑4를 기반으로.
  7. 테일‑리스크 대비 (95번째 백분위 부하).

이러한 체계적인 접근 방식을 따르면 “1 TB ÷ 128 MB = 8 000 파티션”이라는 수준을 훨씬 넘어서는 완전하고 프로덕션에 적합한 답변을 제시할 수 있습니다.

Cluster Sizing – 구조화된 접근법

1. SLA‑first 사이징이 중요한 이유

  • SLA가 수식을 주도 – SLA가 2시간인데 20분 내에 작업을 완료하도록 클러스터를 설계할 수 없으며, 그 반대도 마찬가지입니다.
  • Throughput‑centric 방정식

[ \text{Required throughput} = \frac{\text{Peak data volume}}{\text{SLA}} ]

[ \text{Node count} = \frac{\text{Required throughput}}{\text{Per‑node effective throughput}} ]

핵심 포인트: 클러스터 사이징은 스토리지 문제가 아니라 처리량(throughput) 문제입니다.

2. 공유‑클러스터 현실

ResourceShared 클러스터에서의 현실
CPU cores전체 코어를 전부 사용할 수 없습니다
Memory전체 메모리를 전부 사용할 수 없습니다
Shuffle service테넌트 간에 공유됩니다
Concurrency가용성에 직접적인 영향을 줍니다

이러한 요소들을 무시하면 실제 환경에서 “클러스터 수학”이 부정확해집니다.

3. 답해야 할 전체 질문 목록

  1. Peak intermediate size (피크 중간 데이터 크기)
  2. Bottleneck type (CPU, 메모리, shuffle, I/O, 네트워크)
  3. Shuffle volume (셔플 양)
  4. Storage throughput (스토리지 처리량)
  5. SLA target (SLA 목표)
  6. Input variance (크기, 스키마, 스큐)
  7. Isolation model (전용 vs. 공유)

4. 답변을 구체적인 수치로 변환

CalculationWhat you derive
Target partition size파티션당 원하는 크기 (예: 128 MiB)
Required partitionsceil(Peak intermediate size / Target partition size)
Required concurrent tasksRequired partitions / Executors per node
Executors per nodeCPU 코어와 executor당 메모리를 기준으로 산정
Memory per executorExecutor memory = (Node memory – overhead) / Executors per node
Node countceil(Required concurrent tasks / Executors per node)

결과: 수학적으로 근거된 클러스터 구성.
위 질문들에 답하지 않으면 어떤 사이징도 순수한 추측에 불과합니다.

5. “1 TB 데이터를 위해 클러스터를 어떻게 사이징하나요?” – 올바른 답변

나는 원시 데이터 크기로 클러스터를 사이징하지 않는다.
나는 피크 중간 상태, 주된 병목 현상, 그리고 SLA 제약을 기준으로 사이징한다.
데이터 크기는 시작점에 불과하며, 워크로드 행동이 최종 클러스터를 결정한다.

6. 최신 Databricks Runtime (Spark 4.x) – 무엇이 바뀌었나?

Databricks featureWhat it does
Adaptive Query Execution (AQE) (기본 활성화)셔플 파티션을 합치고, 중간 정도의 스큐를 완화
PhotonSQL/DataFrame 워크로드에 대한 CPU 부하 감소
Delta Lake layout strategies스캔 비효율 및 작은 파일 오버헤드 감소
OPTIMIZE작은 파일을 압축
Z‑ORDER다중 컬럼 데이터 로컬리티 향상
Liquid Clustering정적 파티셔닝 및 Z‑ORDER를 동적 클러스터링으로 대체
Predictive Optimization압축 및 유지보수를 자동화

Benefits

  • 파일 압축
  • 데이터 스키핑
  • 읽기 속도 향상
  • 메타데이터 오버헤드 감소

아직도 남아 있는 과제

  • 셔플 비용
  • 스큐
  • 네트워크 한계
  • Spill 동작
  • 피크 중간 압력

핵심 요약: Databricks에서는 클러스터 사이징이 첫 번째 레버라기보다 마지막 레버인 경우가 많습니다. 추상화가 도움이 되지만, 근본적인 분산 시스템 물리 법칙을 없애지는 못합니다.

7. 앞으로의 전망

다음 포스트에서는 서버리스 Spark를 살펴볼 예정입니다 – 클러스터가 “사라질” 때 어떤 변화가 일어나고, 책임이 어떻게 이동하는지, 그리고 기본 제약은 어떻게 유지되는지에 대해 다룹니다.

0 조회
Back to Blog

관련 글

더 보기 »

일이 정신 건강 위험이 될 때

markdown !Ravi Mishrahttps://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fu...