1、combineByKey
作用: 將RDD[(K,V)] => RDD[(K,C)] 表示V的類型可以轉成C兩者可以不同類型。
def combineByKey[C](createCombiner:V =>C ,mergeValue:(C,V) =>C, mergeCombiners:(C,C) =>C):RDD[(K,C)]
def combineByKey[C](createCombiner:V =>C ,mergeValue:(C,V) =>C, mergeCombiners:(C,C) =>C,numPartitions:Int ):RDD[(K,C)]
def combineByKey[C](createCombiner:V =>C ,mergeValue:(C,V) =>C, mergeCombiners:(C,C) =>C,partitioner:Partitioner,mapSideCombine:Boolean=true,serializer:Serializer= null):RDD[(K,C)]
第一個函數和第二個函數默認使用的是HashPartitioner、serialize為null。
說明:
1)createCombiner:在遍歷RDD的數據集合過程中,對于遍歷到的(k,v),如果combineByKey第一次遇到值為k的Key(類型K),那么將對這個(k,v)調用 createCombiner函數,它的作用是將v轉換為c(類型是C,聚合對象的類型,c作為局和對象的初始值)。
2)mergeValue: ? ?在遍歷RDD的數據集合過程中,對于遍歷到的(k,v),如果combineByKey不是第一次(或者第二次,第三次…)遇到值為k的Key(類型K),那么將對這個 (k,v)調用mergeValue函數,它的作用是將v累加到聚合對象(類型C)中,mergeValue的類型是(C,V)=>C,參數中的C遍歷到此處的聚合對象,然后對v 進行聚合得到新的聚合對象值。
3)mergeCombiners:因為combineByKey是在分布式環境下執行,RDD的每個分區單獨進行combineByKey操作,最后需要對各個分區的結果進行最后的聚合,它的函數類型是(C,C)=>C,每個參數是分區聚合得到的聚合對象
例子:
scala> val data = sc.parallelize(List(("1","3"),("1","2"),("1","5"),("2","3")))
scala> val natPairRdd = data.combineByKey(List(_), (c: List[String], v: String) => v::c, (c1: List[String], c2: List[String]) => c1 ::: c2)
scala> natPairRdd.collect
res0: Array[(String, List[String])] = Array((1,List(3, 2, 5)), (2,List(3)))
執行的邏輯示意圖: