park中對鍵值對RDD(pairRDD)基於鍵的聚合函數中,都是通過combineByKey()實現的。
它可以讓用戶返回與輸入數據類型不同的返回值(可以自己配置返回的參數,返回的類型)
首先理解:combineByKey是一個聚合函數,實際使用場景比如,對2個同學的3門考試科目成績,分別求出他們的平均值。
(也就是對3門考試成績進行聚合,用一個平均數來表示)
combineByKey是通過3個內部函數來解決這個問題的:
具體處理過程爲:遍歷分區中的所有元素,因此每一個元素的鍵要麼沒有遇到過,要麼就和之前的鍵相等。
它的參數形式爲:combineByKey(1.createCombiner,2.mergeValue,3.mergeCombiners,4.partioner)
比如,我有一個數組{1,2,1,2,4}
具體流程爲:第一次遇到1,調用createCombiner()函數。
2.第一次遇到2,調用createCombiner()函數。
3.第二次遇到1,調用mergeValue()函數。
4.第二次遇到2,調用mergeValue()函數。
5.第一次遇到4,調用mergeValue()函數。
接下來解釋每一個函數的作用
1.createCombiner():在遍歷過程中,遇到新的鍵,就會調用createCombiner()函數。這個過程會發生在每一個分區內,因爲RDD中有不同的分區,也就有同一個鍵調用多次createCombiner的情況。
2.mergeValue() 遇到已經重複的鍵,調用mergeValue()函數。
3.mergeCombiners() 如果有2個或者更多的分區,會把分區的結果合併。
4.pationer 分區函數()
準備數據:
1 2 3 4 5 6 7 8 |
|
數據爲jack和tom的3門科目成績,要對jack和tom的平均成績進行輸出。
1.遍歷過程中,統計課程的數目,同時計算總分。
1 2 3 |
|
詳解:
x =>(1,x) 將scores的value轉化爲(1,value)的格式
(c1:(Int,Double),newScore)=>(c1._1+1,c1._2+newScore) 遇到重複的key:我們對value的處理過程爲:
之前計算的結果定義爲newScore,對c1:(c1._1,c2._2)處理過程爲:(c1._1+1,c2._2+newScore)
實際意義爲:再次遍歷到jack時,我們將科目數量+1,將統計的總分再加上遍歷到的分數。
(c1:(Int,Double),c2:(Int,Double))=>(c1._1+c2._1,c1._2+c2._2)) 對2個不同的分區c1,c2(這2個分區,他的鍵相同,都是Jack)
最後我們將不同分區的結果相加。
比如我們還有另一個分區("jack",45) 代表c2。我們要將Jack的科目數+1,總分+45. 獲得最終結果
統計得到的結果:得到姓名:科目+總分
1 2 3 |
|