아파치 스파크 RDD 파티셔닝
From CS Wiki
아파치 스파크 RDD 파티셔닝(Apache Spark RDD Partitioning)은 RDD(Resilient Distributed Dataset)의 데이터를 여러 개의 파티션으로 나누어 분산 처리하는 기법이다. 스파크는 파티셔닝을 통해 데이터의 병렬 처리를 최적화하고, 클러스터의 리소스를 효과적으로 활용할 수 있도록 한다.
개요[edit | edit source]
스파크의 RDD는 기본적으로 여러 개의 파티션으로 분할되어 있으며, 각 파티션은 개별적인 노드에서 병렬 처리된다. RDD의 파티셔닝은 성능과 리소스 활용에 중요한 영향을 미치며, 적절한 파티셔닝 전략을 선택하면 데이터 이동 비용을 최소화하고 처리 속도를 향상시킬 수 있다.
- 파티셔닝의 목적
- 작업을 병렬로 처리하여 성능 향상.
- 데이터 이동을 최소화하여 네트워크 부하 감소.
- 특정 키 기반의 연산(예: 그룹화, 조인) 최적화.
RDD 파티셔닝 방식[edit | edit source]
스파크에서는 기본적으로 두 가지 방식의 파티셔닝을 제공한다.
- 해시 파티셔닝(Hash Partitioning)
- 키의 해시 값을 기반으로 데이터를 특정 파티션에 분배.
- 키를 기준으로 데이터를 그룹화하는 작업(예: 그룹바이, 조인)에 적합.
- 범위 파티셔닝(Range Partitioning)
- 키의 정렬 순서를 기준으로 데이터를 균등하게 나눔.
- 데이터가 정렬된 상태에서 처리되어야 하는 경우(예: 범위 기반 쿼리)에 적합.
파티셔닝 설정 및 변경[edit | edit source]
스파크에서는 RDD의 파티셔닝을 설정하고 변경할 수 있다.
기본 파티셔닝[edit | edit source]
RDD는 기본적으로 입력 데이터의 분할 수(예: HDFS 블록 크기)에 따라 자동으로 파티셔닝된다.
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName("PartitioningExample").getOrCreate()
rdd = spark.sparkContext.parallelize(range(10), numSlices=4) # 4개 파티션으로 생성
print(rdd.getNumPartitions()) # 출력: 4
해시 파티셔닝 적용[edit | edit source]
특정 키를 기준으로 해시 파티셔닝을 적용할 수 있다.
rdd = rdd.map(lambda x: (x, x*x)).partitionBy(3)
print(rdd.getNumPartitions()) # 출력: 3
범위 파티셔닝 적용[edit | edit source]
범위 파티셔닝은 주로 정렬된 데이터에서 활용된다.
from pyspark.rdd import RDD
from pyspark.partitioner import RangePartitioner
data = [(i, i*i) for i in range(10)]
rdd = spark.sparkContext.parallelize(data)
partitioned_rdd = rdd.partitionBy(3, partitionFunc=RangePartitioner(3, rdd))
print(partitioned_rdd.getNumPartitions()) # 출력: 3
파티셔닝을 사용하는 연산[edit | edit source]
Spark에서 기본적으로 파티션(partitioner)을 생성하거나 파티션을 설정하는 대표적인 연산은 다음과 같다.
- sortByKey
- 기본적으로 Range Partitioner를 사용하여 데이터를 정렬하며, 명시적으로 파티션을 생성한다.
- 결과 RDD는 range-partitioned이다.
- groupByKey
- Hash Partitioner를 기본으로 사용하여 키 기준으로 데이터를 그룹화한다.
- 결과 RDD는 hash-partitioned이다.
- reduceByKey
- Hash Partitioner를 기본으로 사용하여 키 기준으로 데이터 값을 줄입니다(aggregate).
- 결과 RDD는 hash-partitioned입니다.
- partitionBy
- 사용자가 지정한 Partitioner (HashPartitioner 또는 RangePartitioner 등)에 따라 명시적으로 파티션을 생성한다.
아래 함수들은 사용 시 기존 파티션이 유지되지 않고 변동이 생긴다.
- map
- flatMap
- union
- join, cogroup 등 다른 RDD와의 결합 연산
- distinct
- sortBy
- repartition
- coalesce
파티셔닝이 중요한 이유[edit | edit source]
RDD의 파티셔닝 방식은 성능과 리소스 활용에 중요한 영향을 미친다.
- 적절한 파티셔닝을 사용하면 데이터 셔플링을 줄일 수 있음.
- 조인 및 그룹 연산이 포함된 작업에서 성능 최적화 가능.
- 불균형한 파티션(데이터 스큐)을 방지하여 병렬 처리 성능을 높일 수 있음.
파티셔닝 관련 최적화[edit | edit source]
스파크에서 파티셔닝을 최적화하는 몇 가지 기법이 있다.
- coalesce() 사용
- 불필요한 파티션을 줄여 성능 최적화.
- 예: rdd.coalesce(2) → 파티션 수를 2개로 줄임.
- repartition() 사용
- 데이터를 다시 분배하여 균등한 파티셔닝을 수행.
- 예: rdd.repartition(4) → 4개 파티션으로 재구성.
- 데이터 스큐 해결
- 특정 키에 데이터가 몰리는 현상을 방지하기 위해 추가적인 샤딩 키를 활용.
응용[edit | edit source]
RDD의 파티셔닝 기법은 다양한 데이터 처리 작업에서 활용된다.
- 대규모 로그 분석
- 서버 로그 데이터를 특정 키(예: 사용자 ID, 타임스탬프) 기반으로 파티셔닝하여 분석.
- 분산 데이터베이스 쿼리 최적화
- 키-값 저장소에서 특정 범위의 데이터를 빠르게 검색.
- 머신러닝 데이터 전처리
- 훈련 데이터를 균등하게 나누어 병렬 처리.
같이 보기[edit | edit source]
참고 문헌[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.