Apache Spark는 대규모 데이터 처리를 위한 통합 분석 엔진입니다. 메모리 기반 연산을 통해 Hadoop MapReduce보다 10~100배 빠른 성능을 제공하며, 배치 처리, 실시간 스트림 처리, SQL 쿼리, 머신러닝, 그래프 처리를 하나의 프레임워크로 통합합니다.
Spark Core 위에 Spark SQL, Spark Streaming, MLlib, GraphX가 통합된 레이어드 아키텍처. 하나의 API로 다양한 작업 처리 가능.
RDD(Resilient Distributed Dataset)를 메모리에 유지하여 반복적 연산(머신러닝 알고리즘 등)에서 극적인 성능 향상.
단일 노드에서 수천 개의 노드 클러스터까지 확장 가능. YARN, Mesos, Kubernetes 또는 Spark Standalone으로 실행.
Spark는 기존 대안들(Hadoop MapReduce, Storm, 기존 DB)을 넘어서는 성능과 통합성을 제공합니다.
| 대안 | 한계점 | Spark의 장점 |
|---|---|---|
| Hadoop MapReduce | 배치만 가능, 디스크 I/O 병목, 복잡한 프로그래밍 모델 | 배치+스트림 통합, 메모리 연산, 간결한 API(Java/Scala/Python/R) |
| Apache Storm | 스트림 처리만 전문, 배치 처리 별도 필요 | 마이크로 배치로 스트림 처리(Spark Streaming), 동일 코드로 배치 가능 |
| 기존 DB/ETL 도구 | 대규모 데이터 확장성 부족, 실시간 처리 어려움 | 분산 처리로 PB급 데이터, 실시간 분석 가능 |
1. 성능: 메모리 캐싱으로 반복 작업 빠름
2. 통합성: 하나의 프레임워크로 배치, 스트림, ML, SQL 처리
3. 생산성 Python, SQL 등 다양한 언어 지원으로 개발 편의성 높음
Spark는 메모리 사용이 많으므로 spark.executor.memory, spark.memory.fraction 설정이 중요합니다. OOM(Out Of Memory)은 자주 발생하는 문제입니다.
# Python 패키지 설치 (PySpark)
pip install pyspark
# 또는 Spark 바이너리 직접 다운로드 (Scala/Java)
wget https://archive.apache.org/dist/spark/spark-3.5.0/spark-3.5.0-bin-hadoop3.tgz
tar -xzf spark-3.5.0-bin-hadoop3.tgz
export SPARK_HOME=~/spark-3.5.0-bin-hadoop3
export PATH=$PATH:$SPARK_HOME/bin
# Spark Session 생성 (Python)
from pyspark.sql import SparkSession
spark = SparkSession.builder \
.appName("QuickStart") \
.master("local[*]") \ # 로컬 모든 코어 사용
.config("spark.executor.memory", "2g") \
.getOrCreate()
# CSV 파일 읽기
df = spark.read.csv("sales.csv", header=True, inferSchema=True)
# 데이터 확인
df.show(5)
df.printSchema()
# 간단한 집계 연산
summary = df.groupBy("category").agg(
{"sales": "sum", "profit": "avg"}
)
summary.show()
# SQL 쿼리 실행 (TempView 생성)
df.createOrReplaceTempView("sales_view")
sql_result = spark.sql("SELECT category, COUNT(*) FROM sales_view GROUP BY category")
sql_result.show()
# SparkContext 종료 (세션 종료)
spark.stop()
Spark는 독립적인 애플리케이션으로도 실행 가능합니다.
# Spark Submit 예제 (Python 애플리케이션)
$SPARK_HOME/bin/spark-submit \
--master local[4] \
--executor-memory 2g \
my_spark_app.py
# Scala/Java 애플리케이션
$SPARK_HOME/bin/spark-submit \
--master yarn \
--class com.example.MyApp \
my-spark-job.jar
성능 튜닝과 클러스터 운영에 필수적인 설정들입니다.
| 설정 키 | 설명 | 권장값 예시 |
|---|---|---|
| spark.executor.memory | 각 Executor의 메모리 크기 | 4g ~ 8g (데이터 크기에 따라) |
| spark.driver.memory | Driver 프로세스 메모리 | 2g ~ 4g |
| spark.executor.instances | Executor 개수 (YARN/Mesos) | 클러스터 노드 수 × (노드 코어 수 / executor 코어) |
| spark.sql.shuffle.partitions | Shuffle 후 파티션 수 (성능 영향 큼) | 200 (기본), 대량 데이터는 1000+ |
| spark.default.parallelism | RDD 연산 기본 병렬도 | Executor 수 × 코어 수 × 2~3 |
| spark.memory.fraction | Execution/Storage 메모리 비율 | 0.6 (기본), 캐싱 많으면 0.8 |
| spark.serializer | 네트워크 전송 시 직렬화 방식 | KryoSerializer (성능 좋음) |
원인: 데이터 크기 > 메모리, 파티션 수 부족.
해결: spark.executor.memory 증가, 파티션 수 조정(spark.sql.shuffle.partitions), 데이터 압축 사용.
원인: groupBy, join 등으로 대량 데이터 이동.
해결: Broadcast Join 사용(소형 테이블), 파티션 수 적절화, 디스크 기반 shuffle 옵션.
원인: 데이터 스큐, 불필요한 직렬화.
해결: Spark UI로 스테이지 분석, 데이터 샘플링으로 스큐 확인, KryoSerializer 적용.
.cache() 또는 .persist()로 메모리/디스크 캐싱.고수준 API(DataFrame/Dataset)는 Catalyst 옵티마이저로 성능이 좋습니다. RDD는 낮은 수준의 컨트롤이 필요할 때만 사용하세요.