러닝스푼즈 - 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처럼 특정 키를 기준으로 데이터를 모은 후 집계하는 경우
