摘要:
RDD:彈性分布式資料集,是一種特殊集合 ‚ 支援多種來源 ‚ 有容錯機制 ‚ 可以被緩衝 ‚ 支援並行操作,一個RDD代表一個分區裡的資料集
RDD有兩種操作運算元: Transformation(轉換):Transformation屬於延遲計算,當一個RDD轉換成另一個RDD時並沒有立即進行轉換,僅僅是記住 了資料集的邏輯操作
Ation(執行):觸發Spark作業的運行,真正觸發轉換運算元的計算
本系列主要講解Spark中常用的函數操作:
1.RDD基本轉換
2.鍵-值RDD轉換
3.Action操作篇 本發所講函數 1.reduce
2.collect 3.count 4.first 5.take 6.top 7.takeOrdered 8.countByKey 9.collectAsMap 10.lookup 11.aggregate 12.fold 13.saveAsFile 14.saveAsSequenceFile 1.reduce(func):通過函數func 先聚集各分區的資料集,再聚集分區之間的資料,func接收兩個參數,返回一個新值,新值再做為參數繼續傳遞給函數func,直到最後一個元素 2.collect():以資料的形式返回資料集中的所有元素給Driver程式,為防止Driver程式記憶體溢出,一般要控制返回的資料集大小
3.count():返回資料集元素個數
4.first():返回資料集的第一個元素 5.take(n):以數組的形式返回資料集上的前n個元素 6.top(n):按預設或者指定的定序返回前n個元素,預設按降序輸出 7.takeOrdered(n,[ordering]): 按自然順序或者指定的定序返回前n個元素 例1:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
def main(args: Array[String]) { val conf = new SparkConf().setMaster( "local" ).setAppName( "reduce" ) val sc = new SparkContext(conf) val rdd = sc.parallelize( 1 to 10 , 2 ) val reduceRDD = rdd.reduce(_ + _) val reduceRDD1 = rdd.reduce(_ - _) //如果分區資料為1結果為 -53 val countRDD = rdd.count() val firstRDD = rdd.first() val takeRDD = rdd.take( 5 ) //輸出前個元素 val topRDD = rdd.top( 3 ) //從高到底輸出前三個元素 val takeOrderedRDD = rdd.takeOrdered( 3 ) //按自然順序從底到高輸出前三個元素 println( "func +: " +reduceRDD) println( "func -: " +reduceRDD1) println( "count: " +countRDD) println( "first: " +firstRDD) println( "take:" ) takeRDD.foreach(x => print(x + " " )) println( "\ntop:" ) topRDD.foreach(x => print(x + " " )) println( "\ntakeOrdered:" ) takeOrderedRDD.foreach(x => print(x + " " )) sc.stop } |
輸出: func +: 55func -: 15 //如果分區資料為1結果為 -53count: 10first: 1take:1 2 3 4 5top:10 9 8takeOrdered:1 2 3
(RDD依賴圖:紅色塊表示一個RDD區,黑色塊表示該分區集合,下同) (RDD依賴圖)
8.countByKey():
作用於K-V類型的RDD上,統計每個key的個數,返回(K,K的個數) 9.collectAsMap():作用於K-V類型的RDD上,作用與collect不同的是collectAsMap函數不包含重複的key,對於重複的key。後面的元素覆蓋前面的元素
10.lookup(k)
:作用於K-V類型的RDD上,返回指定K的所有V值 例2:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
def main(args: Array[String]) { val conf = new SparkConf().setMaster( "local" ).setAppName( "KVFunc" ) val sc = new SparkContext(conf) val arr = List(( "A" , 1 ), ( "B" , 2 ), ( "A" , 2 ), ( "B" , 3 )) val rdd = sc.parallelize(arr, 2 ) val countByKeyRDD = rdd.countByKey() val collectAsMapRDD = rdd.collectAsMap() println( "countByKey:" ) countByKeyRDD.foreach(print) println( "\ncollectAsMap:" ) collectAsMapRDD.foreach(print) sc.stop } |
輸出: countByKey:(B,2)(A,2)collectAsMap:(A,2)(B,3)
(RDD依賴圖)
11.aggregate(zeroValue:U)(seqOp:(U,T) => U,comOp(U,U) => U):
seqOp函數將每個分區的資料彙總成類型為U的值,comOp函數將各分區的U類型資料彙總起來得到類型為U的值
| 1 2 3 4 5 6 7 8 |
def main(args: Array[String]) { val conf = new SparkConf().setMaster( "local" ).setAppName( "Fold" ) val sc = new SparkContext(conf) val rdd = sc.parallelize(List( 1 , 2 , 3 , 4 ), 2 ) val aggregateRDD = rdd.aggregate( 2 )(_+_,_ * _) println(aggregateRDD) sc.stop } |
輸出:
90
步驟1:分區1:zeroValue+1+2=5 分區2:zeroValue+3+4=9 步驟2:zeroValue*分區1的結果*分區2的結果=90 (RDD依賴圖)
12.fold(zeroValue:T)(op:(T,T) => T):
通過op函數彙總各分區中的元素及合并各分區的元素,op函數需要兩個參數,在開始時第一個傳入的參數為zeroValue,T為RDD資料集的資料類型,,其作用相當於SeqOp和comOp函數都相同的aggregate函數 例3