러닝스푼즈 - Practical Spark 강의와 스파크 완벽 가이드 를 요약한 내용입니다.
Spark를 사용하여
가 가능한데, 이러한 작업들을 할 때 Spark의 내부 동작 과정이 발생
filter()
, map()
등 다양한 Transformation을 적용하는 것을 반복count()
와 같은 Action을 호출해 결과를 만들어 내는데 이를 지연연산(Lazy Evaluation)이라 함지연연산(Lazy Evaluation)은 Spark가 연산 그래프를 처리하기 직전까지 기다리는 동작 방식을 의미한다. 특정 연산 명령이 내려진 즉시 데이터를 수정하지 않고, 적용할 Transformation 의 실행 계획을 생성하고 그것을 기반으로 분석하고 최적화 한 뒤 실제 데이터 처리를 물리적으로 실행한다.
explain()
함수를 통해 Spark DataFrame의 실행계획을 확인할 수 있다.
Spark는 DataFrame / SQL / DataSet API를 Catalyst Optimizer를 통해 최적화하고 최종적으로 RDD를 위한 코드를 생성
DataFrame/Dataset/SQL을 이용해 코드를 작성
스파크가 논리적 실행 계획(Logical plan)으로 변환
논리적 실행 계획을 물리적 실행 계획(Physical plan)으로 변환하며 최적화
df.explain("cost")
, df.explain("codegen")
을 통해 비용 확인 가능클러스터에서 물리적 실행 계획(RDD 처리)을 실행
Partition 관련 설정들
spark.default.paralleism
: 주로 spark-default.conf에 세팅되어 초기값으로 사용spark.sql.shuffle.partitions
: DataFrame.repartition()
에서 지정된 숫자가 없을 경우나 Join 이나 Aggregation 등 Shuffle이 발생할 경우 사용spark.sql.files.maxPartitionBytes
, spark.sql.files.minPartitionNum
: 파일을 읽을 때 파일 사이즈를 기반으로 파티션 숫자를 동적으로 계산하기 위해 사용DataFrame.repatition()
은 Partition 을 늘리고 줄일 수 있지만 이 경우 전체 데이터, 즉 전체 Partition 대해 균등하게 배분하기 위해 재배치가 (relocation) 이 발생DataFrame.coalesce()
는 Partition 을 현재 숫자 이하로만 줄이는 것이 가능DataFrame.repartition()
과 달리 줄이는 과정에서 만약 옮길 필요가 없는 데이터가 있다면 옮기지 않아서 비싼 네트워크 연산을 피할 수 있음
repartition()
을 호출하는 경우
- DataFrame 을 가공하는 과정에서 데이터의 불균형 (Skew) 이 발생할 수 있음
- 데이터 가공 후 특정 Partition 데이터만 많이 남아있다면 분산 처리를 한다 해도 특정 Partition 데이터의 양이 많아 상대적으로 늦게 끝날 수 있음
- 가공하는 과정에서 충분한 필터링으로 인해 데이터의 양이 줄었을 경우 Partition 을 줄일 수 있음
- 반대로, DataFrame 을 가공하는 과정에서 Join, Union 등 을 통해 추가적으로 데이터가 늘었을 경우 Partition 을 늘릴 수 있음
Group By
, window function
등을 수행하는 경우가 많으며, 이로인해 잦은 데이터의 이동이 발생할 수 있음Dataframe.repartition()
을 작업 해놓고, 이후 Transformation 에서 해당 Column 을 기준으로 연산을 수행한다면 추가적인 데이터의 이동을 줄일 수 있음df.repartition(col('id'))
트랜스포메이션에는 두 가지 유형이 존재
- 좁은 의존성(Narrow dependency)
- 좁은 의존성을 가진 Transformation은 각 입력 Partition이 하나의 출력 Partition에만 영향을 미침
- 즉 데이터의 이동이 필요없는, Shuffle이 발생하지 않는 Transformation으로
map
,filter
,union
등이 여기에 해당- 넓은 의존성(Wide dependency)
- 넓은 의존성을 가진 Transformation은 하나의 입력 Partition이 여러 출력 Partion에 영향을 미침
group by distinct count
처럼 특정 키를 기준으로 데이터를 모은 후 집계하는 경우