데이터를 합치거나 하나로 줄이는 작업들
Shuffle은 이럴때 발생한다
파티셔닝을 이용해서 셔플링을 최소화 할 수 있음
안좋은 예) groupByKeys + Reduce
파티션에서 Key별로 데이터를 수집 후 Reduce를 진행
좋은 예) ReduceByKey
각각의 파티션에서 Reduce를 거친 후 groupBy를 하기 때문에 파티션에 담기는 데이터의 수가 훨씬 적음
# reduceByKey
(textRDD
.flatMap(lambda line: line.split())
,map(lambda word: (word, 1))
.reduceByKey(lambda a, b: a + b))
# groupByKey
(textRDD
.flatMap(lambda line: line.split())
.map(lambda word: (word, 1))
.groupByKey()
.map(lambda (w, counts): (w, sum(counts))))
노드를 통해 전달되는 데이터의 양이 많아 out of disk 문제 발생 가능
셔플을 최소화해서 10배의 성능 향상이 가능하다!
데이터가 어느 노드/파티션에 들어가는지는 어떻게 결정될까?
Partition의 목적: 데이터를 최대한 균일하게 퍼트리고 쿼리가 같이 되는 데이터를 최대한 옆에 두어 검색 성능을 향상시키는 것
Partition의 특징
스파크의 파티셔닝 == 일반 프로그래밍에서 자료구조를 선택하는 것
Partition 1:[2,4,6,8,10, ...]
Partition 2:[]
이러한 경우를 Data skew 문제라고 칭함
데이터가 한쪽으로 쏠리는 문제라고하며, 분산 환경의 Software라면 겪을 수 밖에 없는 문제라고 한다
기본적으로는 node간 데이터 처리량이 달라 다수의 node들이 소수의 node의 작업이 끝나기를 기다리는 문제라고 한다
서비스의 쿼리 패턴이 날짜 위주면 일별 Range Partition 고려
사용자가 지정한 파티션을 가지는 RDD를 생성하는 함수
>>> pairs = sc.parallelize([1,2,3,4,2,4,1]).map(lambda x: (x, x))
>>> pairs.collect()
[(1,1),(2,2),(3,3),(4,4),(2,2),(4,4),(1,1)]
>>> pairs.partitionBy(2).glom().collect()
[[(2,2),(4,4),(2,2),(4,4)], [(1,1),(3,3),(1,1)]]
glom() : 파티션까지 다 보여주는 Transformation (파티션 형상 확인)
>>> pairs.partitionBy(2, lambda x: x%2).glom().collect()
[[(2,2),(4,4),(2,2),(4,4)], [(1,1),(3,3),(1,1)]]
아래 함수들은 연산중에 새로운 파티션을 만들 수 있다