Spark의 "아키텍처"를 기반으로, Spark 애플리케이션이 실행되는 전체 흐름과 내부 구조를 Driver - Cluster Manager - Executor 관점에서 실제 동작 순서와 데이터 흐름, 그리고 관련 용어들을 정리 (Spark 3.x 기준)
| 구성 요소 | 설명 |
|---|---|
| Driver | 사용자가 작성한 코드가 실행되는 컨트롤 노드. 전체 실행 계획 수립, Task 분배 담당 |
| Cluster Manager | 리소스(CPU, Memory 등)를 할당하고 Executor를 클러스터에 배치함. (ex: YARN, Kubernetes) |
| Executor | 실제 Task를 수행하는 프로세스. 클러스터의 각 노드에 위치하며, 데이터 연산 수행 |
| Catalyst Optimizer | Driver 내부의 쿼리 최적화 엔진. Logical Plan → Optimized Logical Plan → Physical Plan 생성 |
| Tungsten Engine | Executor 내부에서 Physical Plan을 빠르게 실행하기 위한 메모리/CPU 최적화 엔진 |
예시 코드:
spark = SparkSession.builder.getOrCreate()
df = spark.read.csv("users.csv")
df2 = df.filter("age > 20")
df2.show()
SparkSession.builder.getOrCreate() 호출 시:
spark.read.csv() 호출 시:
df.filter("age > 20") 호출 시:
Filter 연산 노드를 추가한 새 Logical Plan 구성df2.show() 같은 Action 실행 시:
Driver는 Physical Plan 기반으로 만들어진 Task들을 Executor에 분배
각 Task는 하나의 데이터 파티션에 해당
Executor는 다음을 수행:
.show()의 경우: Executor는 결과를 Driver로 전송| 용어 | 설명 |
|---|---|
| Transformation | Lazy 연산. ex: filter(), map(), select() 등. DAG에 연산 노드로만 저장됨 |
| Action | 연산을 실행. ex: count(), show(), collect() 등. DAG 실행 트리거 |
| DAG (Directed Acyclic Graph) | Transformation들이 쌓인 연산 그래프. Driver의 Catalyst 내부에서 유지됨 |
| Logical Plan | 사용자의 연산 순서를 추상적으로 표현한 계획. Catalyst가 생성 |
| Optimized Logical Plan | Catalyst가 규칙 기반 최적화를 수행한 계획 |
| Physical Plan | 실제 실행 단계를 포함하는 저수준 계획. 연산 순서/방식 포함 |
| Stage | 하나 이상의 Task로 구성된 실행 단위. 셔플 전/후로 나뉘어 생성됨 |
| Task | 데이터 파티션 단위의 최소 실행 단위. Executor에서 병렬 수행됨 |
| Shuffle | 데이터를 Stage 간 재분배. Join, GroupBy 등 Wide 연산에서 발생함 |
| Broadcast Join | 작은 테이블을 모든 Executor에 복제하여 셔플을 줄이는 기법 |
| Catalyst | Spark의 쿼리 최적화 엔진. Plan을 생성하고 변환함 |
| Tungsten | 실행 시 성능 최적화를 위한 엔진. 메모리/CPU 최적화, 코드 생성 포함 |
| RDD | Spark의 저수준 분산 데이터 구조. DataFrame은 RDD 위에 구성됨 |
| Partition | Task가 처리하는 데이터 단위. 하나의 파일 조각 또는 레코드 블록 |
사용자 코드 (PySpark)
↓
SparkSession → SparkContext (Driver 생성)
↓
Transformation → Logical Plan (Catalyst)
↓
Action 호출
↓
Optimized Logical Plan → Physical Plan → DAG
↓
Stage 나누기 → Task 생성
↓
Cluster Manager 통해 Executor 시작
↓
Task 분배 및 병렬 실행
↓
Executor가 연산 수행 → 결과 Driver로 반환
↓
사용자에게 결과 출력