✅ RDD의 특성
- 파티션 목록
- 각 split을 연산(계산)하는 데에 사용되는 함수
- 의존하는 다른 RDD 목록
- (optional) Key-Value RDD를 위한 파티셔너
- (optional) 각 split이 연산되는 데이 최적의 노드 목록
1️⃣ 파티션 목록 (a list of partitions)
- RDD는 여러 개의 파티션으로 이루어져 있고, 하나의 파티션은 동일한 타입의 여러 개의 객체들로 이루어져 있다.
- RDD의 partitions 함수는 내부적으로 다시
getPartition 함수를 이용하여 Partition 배열 객체를 반환하며, getPartitions 함수의 경우 추상 클래스인 RDD를 상속 받은 하위 RDD 클래스를 반환한다.
getInputFormat에서 getSplits는 Job에 사용되는 입력 파일의 논리적 split을 반환하며, 각 InputSplit은 처리를 위하 각 Mapper에 Assign된다.
- 스파크의 하둡 RDD를 구성하는 파티션은 하둡의 Split과 대응되며, 실제 File Chunk가 아닌 논리적인 정보만을 가지고 있다.
2️⃣ 각 split을 계산하는 함수 (a function for computing each split)
[map 함수]
- Driver Application에서 발생하는 과정
- CleanF 함수를 이용해 주어진 함수 내의 Closure 변수를 제거. 분산 환경에서 주어진 함수를 처리하는 주체가 executor이고, 이 과정에서 함수 밖에 있는 closure 변수에 접근할 수 없기 때문.
- map 함수를 수행하는 시점에서 실제로 값을 계산하지 않고, 주어진 정보를 기반으로 초기화한 RDD를 반환. 실제 연산은 action 계열 연산에서 spark context의 runJob 함수 수행 후 각 executor에서 실행된다.
- 현재 RDD를 전달하여 생성자에서 Dependency 정보를 생성하는데 활용
- Executor에서 Task를 처리하는 과정
- Driver에서 전달한 Task들을 수행. Driver로부터 Serialize된 실행 정보를 전달 받아 Task 객체를 초기화한 후 run 함수에서 Task의 run 함수를 실행
- 우리가 map 함수에 넘겼던 함수를 Parent RDD에 적용하여 우리가 원하는 새로운 RDD를 만든다.
- Task란?
- Execution의 단위
- 스파크에는 두 종류의 Task가 있다.
- ShuffleMapTask
- ResultTask
- 스파크 잡은 1개 이상의 stage로 구성되어 있다. 잡을 구성하는 가장 최종 stage는 여러 개의 ResultTask들로 이루어져 있고, 그 이전 stage들은 ShuffleMapTask로 구성되어 있다.
- ResultTask는 Task를 실행시킨 후 Task의 결과를 Driver Application으로 전송한다. 즉, action에 해당.
- ShuffleMapTask는 Task를 실행시킨 후 Task의 결과를 여러 개의 Bucket으로 나눈다. map, reduce 등의 함수에 해당.
3️⃣ 의존하는 다른 RDD 목록 (a list of dependencies on other RDDs)
- Spark의 Dependency 클래스에는 NarrowDependency, OneToOneDependency, ShuffleDependency 등 다양한 Dependency 클래스가 정의되어 있다.
- NarrowDependency → 예) coalesce 함수. n개의 부모 파티션이 1개의 자식 파티션과 대응
- 스파크는 RDD 간의 관계를 Dependency라는 객체를 통해 저장하고 관리하고 있고, 우리는 이를 Lineage라고 부른다.
[출처]
https://medium.com/@leeyh0216/spark-internal-part-1-rdd의-내부-동작-d50eb7a235e6