無需域名網站建設競價什么意思
一、sortByKey
??SortByKey是一個transformation算子,但是會觸發(fā)action,因為在sortByKey方法內部,會對每個分區(qū)進行采樣,構建分區(qū)規(guī)則(RangePartitioner)。
內部執(zhí)行流程
1、創(chuàng)建RangePartitioner part,用于構建分區(qū)規(guī)則。
??Part可以根據指定的分區(qū)數量和排序方式,確定每個下游分區(qū)的上界,并為每個key分配正確的分區(qū)編號。數據在shuffle到本地磁盤的過程中,會記錄目標分區(qū)的信息,確保下游分區(qū)能夠正確拉取對應分區(qū)的數據。
2、根據part創(chuàng)建ShuffleRDD,對原始RDD按key重新分區(qū)。
3、shuffle到本地磁盤的臨時文件(包含數據文件和索引文件)。
4、下游分區(qū)拉取對應分區(qū)的數據。
RangePatitioner工作原理
(1)確定下游每個分區(qū)的上界。
??對每個上游分區(qū)采樣,確定數據的大致范圍,再根據傳入的分區(qū)數或者默認分區(qū)數確定分區(qū)邊界。
(2)將rdd中的每個key調用getPartition函數,從而獲取其應歸屬的分區(qū)。
①若目標分區(qū)數較小(128),采用線性查找;
②若超過128,采用二分查找:
??如果鍵小于范圍的最小界限,它將分配到第一個分區(qū)。
??如果鍵大于所有范圍界限,它將分配到最后一個分區(qū)。
??對于在某個范圍中間的鍵,getPartition 使用二分查找方法找到合適的分區(qū)。這里根據范圍邊界數組 (rangeBounds) 和鍵值(k)進行比較,返回對應的分區(qū)索引。
二、join
內部執(zhí)行流程
1、接收其他RDD作為參數
??默認使用當前有效的最大分區(qū)器,如果沒有,新建一個HashPartitioner作為分區(qū)器。
2、將具有相同key的value進行聯結(cogroup)
??(返回一個二元組(K, (Iterable[V1], Iterable[V2]))),若某個rdd沒有該key對應的value,Iterable為空。
3、將每個key對應的兩個Iterator中的元素進行笛卡爾積,每一對結果作為新的value,與key組成新的二元組返回。
三、map & mapPartitions & mapPartitionsWithIndex & flatMap
1、map
內部執(zhí)行流程
(1)將函數作為參數傳入;
(2)對f刪除不必要的引用,檢查是否能夠被序列化,是否存在閉包問題;
(3)創(chuàng)建一個MapPartitionsRDD,將每個迭代器執(zhí)行 f
的邏輯后返回。
特點
(1)每處理一條數據,就調用一次f,每一條數據都是一個迭代器。
(2)無法直接得知分區(qū)編號,但是可以通過如下方式獲取:
val index = TaskContext.getPartitionId()
(3)返回迭代器。
2、mapPartitions
特點
(1)以分區(qū)為單位對數據調用f
,一個分區(qū)就是一個迭代器。
(2)返回迭代器和partitioner。
3、mapPartitionsWithIndex
特點
(1)以分區(qū)為單位對數據調用f
,一個分區(qū)就是一個迭代器。
(2)返回分區(qū)編號和迭代器
4、flatMap
??通過TraversableOnce特征,逐個處理rdd中的每個元素,然后將處理過的元素組成新的rdd返回。
四、groupByKey & groupBy
1、groupByKey (k, CompactBuffer(v,v,v,v) )
內部執(zhí)行流程
1、調用 combineByKeyWithClassTag
將所有相同的key合并到CompactBuffer中,并根據指定的partitioner進行分組;
2、返回一個新的rdd,每個key 對應的value被聚合成一個CompactBuffer;
3、將合并后的rdd轉換為RDD[(K, Iterable[V])]]。
partitioner為HashPartitioner
??可以看到,HashPartitioner為key分配新分區(qū)號的方式是key的hashCode值 % 下游分區(qū)數,這意味著相同key的數據一定會被分配到同一臺機器的同一個partition的同一個組里面。
2、groupBy ( k, CompactBuffer( (k,v),(k,v),(k,v),(k,v) ) )
內部執(zhí)行流程
1、將f
函數作為參數傳入;
2、對f刪除不必要的引用,檢查是否能夠被序列化,是否存在閉包問題;
3、將rdd的每個元素調用f
后的值作為key,元素本身作為value,得到的二元組調用groupByKey進行分組。
??源rdd在Driver端被創(chuàng)建和調用,對rdd進行操作,本質上是對rdd的每個partition進行操作,而每個partition對應一個task,task就會對這個partition對應的Iterator進行相應的操作。
??算子被調用,真正執(zhí)行時會調用compute方法。真正執(zhí)行具體是指task被分配到executor的線程池中時,compute方法被iterator調用。
3、groupBy VS groupByKey
??groupBy更靈活,但在shuffle時傳輸的數據更多(groupBy返回 ( k, CompactBuffer( (k,v),(k,v),(k,v),(k,v) ) );而groupByKey返回 (k, CompactBuffer(v,v,v,v) ) )。
五、reduceByKey & combinByKey
1、reduceByKey
內部執(zhí)行流程
1、調用 combineByKeyWithClassTag
,將分區(qū)內相同key的value應用傳入的函數,再將分區(qū)間相同key的value應用同一個傳入的函數;
2、返回一個新的rdd。
2、combineByKey
??combineByKey的內部執(zhí)行流程與reduceByKey是一樣的,唯一不同的是combineByKey分區(qū)間應用的函數與分區(qū)內應用的函數不同。
3、性能分析
ReduceByKey VS CombineByKey
??combineByKey更靈活,因為其支持分別指定分區(qū)內和分區(qū)間的聚合邏輯,而reduceByKey分區(qū)內和分區(qū)間使用一樣的聚合邏輯。
reduceByKey VS groupByKey
??reduceByKey的效率更高,因為reduceByKey在map端會進行局部聚合,因此在shuffle時傳輸的數據更少。
六、foldByKey & aggregateByKey
1、foldByKey
內部執(zhí)行流程
(1)調用 combineByKeyWithClassTag
,先將初始值應用函數,再將分區(qū)內相同key的value應用傳入的函數,最后將分區(qū)間相同key的value應用同一個傳入的函數;
(2)返回一個新的rdd。
2、aggregateByKey
??foldByKey 的內部執(zhí)行流程與 aggregateByKey 是一樣的,唯一不同的是 aggregateByKey 分區(qū)間應用的函數與分區(qū)內應用的函數不同。
3、foldByKey 與 aggregateByKey的區(qū)別
??foldByKey局部和全局使用相同的聚合邏輯;aggregateByKey局部和全局使用不同的聚合邏輯。