아파치 스파크 스테이지
아파치 스파크 스테이지(Apache Spark Stage)는 스파크 작업(Job)을 여러 개의 독립적인 단위로 나누는 실행 단위이다. 스파크 작업은 여러 개의 스테이지로 나누어져 병렬적으로 실행되며, 각 스테이지는 여러 태스크(Task)로 분할된다. 스테이지는 주로 데이터셋에 대한 좁은 변환(Narrow Transformation)과 넓은 변환(Wide Transformation)에 따라 구분된다.
1 개요[edit | edit source]
스파크 작업은 대개 여러 개의 스테이지로 나누어져 실행된다. 각 스테이지는 데이터를 처리하는 작업 단위로, 스파크 클러스터에서 병렬로 실행될 수 있다. 스테이지의 구분은 주로 셔플 연산(shuffle operation)이 발생하는 지점에서 이루어진다. 셔플 연산은 데이터가 네트워크를 통해 이동하며 다시 분배되는 과정을 의미한다.
- 좁은 변환 (Narrow Transformation): 데이터를 재분배하지 않고 하나의 파티션 내에서만 연산을 수행하는 연산으로, 셔플 연산이 발생하지 않는다. 예: `map`, `filter`
- 넓은 변환 (Wide Transformation): 여러 파티션에서 데이터를 재배치하는 연산으로, 셔플 연산이 발생한다. 예: `groupBy`, `join`
2 스테이지의 분할[edit | edit source]
스파크는 셔플 연산이 발생하는 지점에서 스테이지를 나누며, 셔플 연산이 없는 경우에는 동일한 스테이지에서 실행된다.
2.1 스테이지 나누기 예시[edit | edit source]
- 좁은 변환: `rdd.map` 또는 `rdd.filter`와 같은 연산은 셔플을 발생시키지 않으며, 하나의 스테이지에서 처리된다.
- 넓은 변환: `rdd.groupBy`나 `rdd.join`은 셔플을 발생시키며, 이 연산은 새로운 스테이지를 형성한다.
스파크는 이러한 변환을 기반으로 DAG(Directed Acyclic Graph)를 구성하고, 각 스테이지를 순차적으로 처리하면서 셔플을 통한 데이터 이동이 필요한 시점에서 스테이지를 나눈다.
3 스테이지의 실행[edit | edit source]
각 스테이지는 여러 개의 태스크로 분할되어 실행된다. 태스크는 스파크 클러스터의 각 Executor에서 병렬적으로 실행된다. 스파크의 스테이지 실행은 다음과 같은 순서로 이루어진다:
- 첫 번째 스테이지가 실행된다.
- 첫 번째 스테이지가 완료되면, 두 번째 스테이지가 실행된다.
- 두 번째 스테이지에서 셔플이 발생하면, 결과가 네트워크를 통해 분배된다.
- 셔플이 완료되면, 새로운 스테이지가 실행된다.
- 모든 스테이지가 완료되면, 최종 결과가 계산된다.
이 과정에서 스테이지는 독립적으로 병렬 처리되며, 각 스테이지는 이전 스테이지의 데이터를 사용한다. 스파크는 이러한 스테이지의 의존 관계를 관리하여 효율적으로 작업을 스케줄링한다.
4 스테이지 간 의존성[edit | edit source]
스파크에서 스테이지 간 의존성은 좁은 의존성(Narrow Dependency)과 넓은 의존성(Wide Dependency)으로 나눌 수 있다:
- 좁은 의존성(Narrow Dependency): 하나의 파티션에서 다른 파티션의 데이터를 참조하는 연산이다. 예: `map`, `filter`. 이러한 연산은 셔플을 발생시키지 않으며, 동일한 스테이지에서 실행된다.
- 넓은 의존성(Wide Dependency): 여러 파티션에서 데이터를 병합하거나 재분배하는 연산이다. 예: `groupBy`, `join`. 이러한 연산은 셔플을 발생시켜 새로운 스테이지를 형성한다.
스파크는 넓은 의존성이 있을 때마다 새로운 스테이지를 나누어, 셔플을 통해 데이터를 재분배한다.
5 스테이지의 중요성[edit | edit source]
스파크에서 스테이지는 작업을 효율적으로 분할하고, 각 스테이지를 병렬적으로 실행할 수 있게 한다. 스테이지를 적절하게 나누면 성능을 극대화할 수 있으며, 셔플이 발생하는 지점을 관리함으로써 네트워크 비용과 I/O 비용을 줄일 수 있다.
- 성능 최적화: 스테이지를 적절하게 나누어 셔플을 최소화하고, 병렬 처리를 극대화한다.
- 디버깅: 각 스테이지를 독립적으로 디버깅할 수 있어, 오류를 추적하고 수정하는 데 유리하다.
6 스파크 UI에서 스테이지 보기[edit | edit source]
스파크의 실행 상태를 시각적으로 확인할 수 있는 UI에서 각 스테이지의 진행 상황을 볼 수 있다. 스파크 UI에서는 각 스테이지에 대해 다음 정보를 제공한다:
- 스테이지의 상태 (실행 중, 완료 등)
- 각 태스크의 상태 (완료된 태스크, 대기 중인 태스크 등)
- 셔플 발생 여부 및 셔플의 진행 상태
스파크 UI는 `http://localhost:4040`에서 확인할 수 있으며, DAG 그래프와 함께 스테이지의 실행 흐름을 한눈에 확인할 수 있다.
7 예제[edit | edit source]
다음은 간단한 스파크 코드에서 스테이지를 확인하는 예제이다:
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName("StageExample").getOrCreate()
rdd = spark.sparkContext.parallelize([1, 2, 3, 4, 5])
rdd = rdd.map(lambda x: x * 2)
rdd = rdd.filter(lambda x: x > 5)
result = rdd.collect()
print(result)
이 코드에서 `map`과 `filter`는 각각 하나의 스테이지를 형성하며, `collect`가 호출될 때 최종 결과가 출력된다.
8 같이 보기[edit | edit source]
9 참고 문헌[edit | edit source]
- Zaharia, Matei, et al. "Spark: Cluster Computing with Working Sets." USENIX, 2010.
- Chambers, Bill, and Zaharia, Matei. "Spark: The Definitive Guide." O'Reilly Media, 2018.