Spark 핵심 아키텍처 (Driver/Executor/DAG/RDD)
Apache Spark Data Engineering Interview Questions (blog, 50 Q&A) — (블로그, 발행처 미상) spark_ref_01.md Q1-10 (Core Concepts & Architecture)
이 모듈을 다 읽으면
- Spark가 MapReduce와 근본적으로 어떻게 다른 처리 모델을 갖는지 설명할 수 있다
- Driver-Executor-클러스터 매니저 3자의 역할 분담을 설명할 수 있다
- 트랜스포메이션의 지연 평가가 DAG 생성 및 Catalyst 최적화와 어떻게 연결되는지 설명할 수 있다
- SparkSession 등장 이전 SparkContext/SQLContext/HiveContext가 각각 무엇을 담당했는지 구분할 수 있다
Spark의 핵심 실행 모델(Driver-Executor-클러스터 매니저)과 RDD/DAG/지연 평가의 기본 개념을 다룬다. Spark가 MapReduce보다 빠른 이유를 '무조건 100배'가 아니라 워크로드 조건에 따라 달라진다는 관점으로 정리했다.
Spark와 MapReduce, 무엇이 다른가
MapReduce는 각 Map/Reduce 단계마다 중간 결과를 디스크에 기록하기 때문에 반복적인 연산(예: 머신러닝의 반복 학습)에서 디스크 I/O가 누적된다. Spark는 가능한 한 데이터를 메모리(RAM)에 유지한 채로 여러 연산을 이어서 수행하므로 이런 반복 워크로드에서 특히 유리하다.
다만 '최대 100배 빠르다'는 표현은 특정 반복 알고리즘·인메모리 조건에서 관측된 수치이지 일반적인 보장이 아니다. 데이터가 메모리에 다 들어가지 않아 디스크로 스필(spill)되는 경우, 혹은 반복이 없는 단순 1회성 배치 스캔에서는 그 격차가 훨씬 작아지거나 무의미해질 수 있다. 학습할 때는 '항상 100배'가 아니라 '워크로드와 메모리 조건에 따라 다르다'로 이해하는 것이 안전하다.
핵심 포인트
- Spark의 속도 우위는 주로 반복적·인메모리 워크로드에서 두드러지며, 조건에 따라 격차가 크게 줄어들 수 있다.
- MapReduce는 단계마다 디스크에 중간 결과를 쓰는 반면 Spark는 메모리 내에서 여러 연산을 체이닝한다.
- Spark는 SQL/스트리밍/ML/그래프 처리를 하나의 통합 엔진으로 제공한다는 점도 MapReduce 생태계와의 큰 차이다.
Spark 생태계 구성 요소
Spark Core는 태스크 스케줄링, 메모리 관리, 장애 복구 등 기본 실행 엔진을 담당한다. 그 위에 SQL/DataFrame 처리를 위한 Spark SQL, 스트림 처리를 위한 Structured Streaming, 머신러닝을 위한 MLlib, 그래프 연산을 위한 GraphX가 라이브러리 형태로 얹혀 있다.
주의할 점: 원문은 'Spark Streaming / Structured Streaming'을 나란히 언급하지만, DStream 기반의 구(舊) Spark Streaming은 사실상 레거시로 취급되고 신규 개발에는 권장되지 않는다. 2026년(Spark 3.5+/4.x) 기준 스트림 처리 학습·실무는 Structured Streaming을 중심으로 이루어진다. GraphX 역시 오랫동안 큰 업데이트가 없는 상태라 실무에서는 GraphFrames 같은 대안이 언급되기도 한다.
핵심 포인트
- Spark Core 위에 SQL/스트리밍/MLlib/GraphX가 라이브러리로 얹힌 계층 구조다.
- DStream 기반 구 Spark Streaming은 레거시이며, 현재는 Structured Streaming이 표준이다.
- GraphX는 유지보수 속도가 느려 실무에서 대체재가 거론되기도 한다.
RDD — Resilient Distributed Dataset
RDD는 Spark의 가장 근본적인 분산 데이터 구조로, 불변(immutable)이며 여러 노드에 파티션 단위로 분산된 객체 컬렉션이다. 'Resilient(회복력 있는)'라는 이름은 RDD가 자신을 만들어낸 연산의 계보(lineage)를 기억하고 있어서, 노드 장애로 특정 파티션이 유실되어도 원본 데이터로부터 해당 연산을 다시 수행해 복구할 수 있다는 뜻이다.
핵심 포인트
- RDD는 불변 객체이며 파티션 단위로 클러스터에 분산된다.
- lineage(계보)를 통해 장애 시 데이터를 재계산으로 복구한다는 점이 'Resilient'의 의미다.
Driver, Executor, 클러스터 매니저의 역할
Driver는 사용자 코드의 main()이 실행되는 프로세스이며, 연산을 논리적 DAG로 변환하고 이를 스테이지·태스크로 쪼개 Executor에 스케줄링하는 '두뇌' 역할을 한다. count()나 collect() 같은 액션의 결과도 Driver로 모인다.
Executor는 각 워커 노드에서 실행되는 프로세스로, Driver가 할당한 태스크를 실제로 수행하고 데이터를 메모리나 디스크에 저장한다. 하나의 애플리케이션에 속한 Executor들은 애플리케이션이 종료될 때까지 유지되는 것이 기본 동작이며(Dynamic Allocation을 켜면 유휴 Executor가 중간에 반납될 수 있다), Executor가 실패하면 Driver가 다른 Executor에 태스크를 재실행한다.
클러스터 매니저(Standalone/YARN/K8s 등)는 Driver의 리소스 요청을 받아 Executor를 실제로 실행시키는 역할을 하며, Spark 자체의 태스크 스케줄링 로직과는 별개의 계층이다.
핵심 포인트
- Driver는 DAG 생성, 스테이지/태스크 분할, 스케줄링, 결과 수집을 담당한다.
- Executor는 태스크 실행과 데이터 캐싱을 담당하며 기본적으로 애플리케이션 생명주기 동안 유지된다.
- 클러스터 매니저는 Driver의 요청에 따라 Executor를 실제로 실행시키는 별도 계층이다.
DAG, 트랜스포메이션/액션, 지연 평가
트랜스포메이션(map, filter, groupByKey 등)을 호출할 때마다 Spark는 실제로 연산을 실행하지 않고 DAG(방향성 비순환 그래프)에 해당 연산을 기록하기만 한다. 이를 '지연 평가(lazy evaluation)'라 하며, count()·collect() 같은 액션이 호출되어야 비로소 지금까지 쌓인 DAG 전체가 DAG 스케줄러에 제출되어 스테이지로 최적화·분할된 뒤 실행된다.
지연 평가의 실질적 이점은 Catalyst 옵티마이저(DataFrame/SQL 경로)가 개별 연산을 하나씩 즉시 실행하는 대신 체인 전체를 미리 보고 필터를 합치거나 불필요한 데이터 읽기를 건너뛰는 등 전역적으로 최적화할 수 있다는 점이다. 트랜스포메이션은 셔플 유발 여부에 따라 narrow/wide로 나뉘는데, 이는 모듈 2에서 다룬다.
핵심 포인트
- 트랜스포메이션은 기록만 되고, 액션이 호출될 때 DAG 전체가 실행된다(지연 평가).
- 지연 평가 덕분에 Catalyst가 전체 실행 계획을 보고 최적화할 여지가 생긴다.
- DAG는 셔플 경계를 기준으로 여러 스테이지로 나뉜다.
SparkSession으로의 통합
Spark 2.0 이전에는 RDD 연산용 SparkContext, SQL 연산용 SQLContext, Hive 연동용 HiveContext를 각각 따로 만들어 관리해야 했다. Spark 2.0부터 도입된 SparkSession은 이 세 가지 기능을 하나의 진입점으로 통합해 API를 단순화했다.
이 통합 자체는 이미 오래된 사실(2016년 Spark 2.0)이라 최신성 이슈는 없지만, 실무 관점에서 덧붙이면 SparkSession 내부에서도 spark.sparkContext로 기존 SparkContext에 여전히 접근 가능하며, RDD 저수준 API를 다뤄야 할 때 이 경로를 사용한다.
핵심 포인트
- Spark 2.0부터 SparkContext/SQLContext/HiveContext가 SparkSession 하나로 통합되었다.
- SparkSession 내부에서도 spark.sparkContext로 기존 RDD API에 접근할 수 있다.