好程式設計師大資料學習路線分享彈性分散式資料集RDD
好程式設計師大資料學習路線分享彈性分散式資料集RDD,RDD定義,RDD(Resilient Distributed Dataset)叫做分散式資料集,是Spark中最基本的資料抽象,它代表一個 不可變(資料和後設資料)、可分割槽、裡面的元素 可平行計算的集合。
RDD的特點:自動容錯,位置感知性排程和可伸縮性
RDD的屬性
1.一組分片
即資料集的基本組成單位。對於RDD來說,每個分片都會被一個計算任務處理,並決定平行計算的粒度。使用者可以在建立RDD時指定RDD的分片個數,如果沒有指定,那麼就會採用預設值。預設值就是程式所分配到的CPU Core的數目。
2.一個計算每個分割槽的函式。
Spark中RDD的計算是以分片為單位的,每個RDD都會實現compute函式以達到這個目的。compute函式會對迭代器進行復合,不需要儲存每次計算的結果。
3.RDD之間的依賴關係。
RDD的每次轉換都會生成一個新的RDD,所以RDD之間就會形成類似於流水線一樣的前後依賴關係。
容錯處理: 在部分分割槽資料丟失時,Spark可以透過這個依賴關係重新計算丟失的分割槽資料,而不是對RDD的所有分割槽進行重新計算。
4.一個Partitioner,分割槽器
即RDD的分片函式。當前Spark中實現了兩種型別的分片函式,一個是基於雜湊的HashPartitioner,另外一個是基於範圍的RangePartitioner。只有對於key-value的RDD,才會有Partitioner,非key-value的RDD的Parititioner的值是None。Partitioner函式不但決定了RDD本身的分片數量,也決定了parent RDD Shuffle輸出時的分片數量。
5.一個列表
儲存存取每個Partition的優先位置(preferred location)。-> 就近原則
對於一個HDFS檔案來說, 這個列表儲存的就是每個Partition所在的塊的位置。按照“移動資料不如移動計算”的理念,Spark在進行任務排程的時候,會盡可能地將計算任務分配到其所要處理資料塊的儲存位置。
RDD型別
1.Transformation -> 記錄計算過程(記錄引數,計算方法)
轉換 |
含義 |
map(func) |
返回一個新的RDD,該RDD由每一個輸入元素經過func函式轉換後組成 |
filter(func) |
返回一個新的RDD,該RDD由經過func函式計算後返回值為true的輸入元素組成 |
flatMap(func) |
類似於map,但是每一個輸入元素可以被對映為0或多個輸出元素(所以func應該返回一個序列,而不是單一元素) |
mapPartitions(func) |
類似於map,但獨立地在RDD的每一個分片上執行,因此在型別為T的RDD上執行時,func的函式型別必須是Iterator[T] => Iterator[U] |
mapPartitionsWithIndex(func) |
類似於mapPartitions,但func帶有一個整數參數列示分片的索引值,因此在型別為T的RDD上執行時,func的函式型別必須是 (Int, Iterator[T]) => Iterator[U] |
sample(withReplacement, fraction, seed) |
根據fraction指定的比例對資料進行取樣,可以選擇是否使用隨機數進行替換,seed用於指定隨機數生成器種子 |
union(otherDataset) |
對源RDD和引數RDD求並集後返回一個新的RDD |
intersection(otherDataset) diff -> 差集 |
對源RDD和引數RDD求交集後返回一個新的RDD |
distinct([numTasks])) [改變分割槽數] |
對源RDD進行去重後返回一個新的RDD |
groupByKey([numTasks]) |
在一個(K,V)的RDD上呼叫,返回一個(K, Iterator[V])的RDD |
reduceByKey(func, [numTasks]) |
在一個(K,V)的RDD上呼叫,返回一個(K,V)的RDD,使用指定的reduce函式,將相同key的值聚合到一起,與groupByKey類似,reduce任務的個數可以透過第二個可選的引數來設定 |
aggregateByKey(zeroValue)(seqOp, combOp, [numTasks]) |
|
sortByKey([ascending], [numTasks]) |
在一個(K,V)的RDD上呼叫,K必須實現Ordered介面,返回一個按照key進行排序的(K,V)的RDD |
sortBy(func,[ascending], [numTasks]) |
與sortByKey類似,但是更靈活 |
join(otherDataset, [numTasks]) |
在型別為(K,V)和(K,W)的RDD上呼叫,返回一個相同key對應的所有元素對在一起的(K,(V,W))的RDD |
cogroup(otherDataset, [numTasks]) |
在型別為(K,V)和(K,W)的RDD上呼叫,返回一個(K,(Iterable<V>,Iterable<W>))型別的RDD |
cartesian(otherDataset) |
笛卡爾積 |
pipe(command, [envVars]) |
|
coalesce(numPartitions) |
|
repartition(numPartitions) |
重新分割槽 |
repartitionAndSortWithinPartitions(partitioner) |
|
2.Action -> 觸發生成job(一個job對應一個action運算元)
動作 |
含義 |
reduce ( func ) |
透過func函式聚集RDD中的所有元素,這個功能必須是可交換且可並聯的 |
collect () |
在驅動程式中,以陣列的形式返回資料集的所有元素 |
count () |
返回RDD的元素個數 |
first () |
返回RDD的第一個元素(類似於take(1)) |
take ( n ) |
取資料集的前n個元素組成的陣列 |
takeSample ( withReplacement , num , [ seed ]) |
返回一個陣列,該陣列由從資料集中隨機取樣的num個元素組成,可以選擇是否用隨機數替換不足的部分,seed用於指定隨機數生成器種子 |
takeOrdered ( n , [ordering] ) |
takeOrdered和top類似,只不過以和top相反的順序返回元素 |
saveAsTextFile ( path ) |
將資料集的元素以textfile的形式儲存到HDFS檔案系統或者其他支援的檔案系統,對於每個元素,Spark將會呼叫toString方法,將它裝換為檔案中的文字 |
saveAsSequenceFile ( path ) |
將資料集中的元素以Hadoop sequencefile的格式儲存到指定的目錄下,可以使HDFS或者其他Hadoop支援的檔案系統。 |
saveAsObjectFile ( path ) |
|
countByKey () |
針對(K,V)型別的RDD,返回一個(K,Int)的map,表示每一個key對應的元素個數。 |
foreach ( func ) |
在資料集的每一個元素上,執行函式func進行更新。 |
建立RDD
Linux進入sparkShell:
/usr/local/spark.../bin/spark-shell \
--master spark://hadoop01:7077 \
--executor-memory 512m \
--total-executor-cores 2
或在Maven下:
object lx03 { def main(args: Array[String]): Unit = { val conf : SparkConf = new SparkConf() .setAppName("SparkAPI") .setMaster("local[*]")
val sc: SparkContext = new SparkContext(conf) //透過並行化生成rdd val rdd1: RDD[Int] = sc.parallelize(List(24,56,3,2,1)) //對add1的每個元素乘以2然後排序 val rdd2: RDD[Int] = rdd1.map(_ * 2).sortBy(x => x,true)
println(rdd2.collect().toBuffer) //過濾出大於等於10的元素 // val rdd3: RDD[Int] = rdd2.filter(_ >= 10)
// println(rdd3.collect().toBuffer) } |
練習2
val rdd1 = sc.parallelize(Array("a b c", "d e f", "h i j")) //將rdd1裡面的每一個元素先切分在壓平 val rdd2 = rdd1.flatMap(_.split(' ')) rdd2.collect //複雜的: val rdd1 = sc.parallelize(List(List("a b c", "a b b"), List("e f g", "a f g"), List("h i j", "a a b"))) //將rdd1裡面的每一個元素先切分在壓平 val rdd2 = rdd1.flatMap(_.flatMap(_.split(" "))) |
練習3
val rdd1 = sc.parallelize(List(5, 6, 4, 3)) val rdd2 = sc.parallelize(List(1, 2, 3, 4)) //求並集 val rdd3 = rdd1.union(rdd2)
//求交集 val rdd4 = rdd1.intersection(rdd2) //去重 rdd3.distinct.collect rdd4.collect |
練習4
val rdd1 = sc.parallelize(List(("tom", 1), ("jerry", 3), ("kitty", 2))) val rdd2 = sc.parallelize(List(("jerry", 2), ("tom", 1), ("shuke", 2))) //求join val rdd3 = rdd1.join(rdd2) -> 相同的key組成新的key,value //結果: Array[(String,(Int,Int))] = Array((tom,(1,1)),(jerry,(3,2))) rdd3.collect //求左連線和右連線 val rdd3 = rdd1.leftOuterJoin(rdd2) rdd3.collect val rdd3 = rdd1.rightOuterJoin(rdd2) rdd3.collect //求並集 val rdd4 = rdd1 union rdd2 //按key進行分組 rdd4.groupByKey rdd4.collect //分別用groupByKey和reduceByKey實現單詞計數 val rdd3 = rdd1 union rdd2 rdd3.groupByKey().mapValues(_.sum).collect rdd3.reduceByKey(_+_).collect |
groupByKey和reduceByKey的區別
reduceByKey運算元比較特殊,它首先會進行區域性聚合,再全域性聚合,我們只需要傳一個區域性聚合的函式就可以了
練習5
val rdd1 = sc.parallelize(List(("tom", 1), ("tom", 2), ("jerry", 3), ("kitty", 2))) val rdd2 = sc.parallelize(List(("jerry", 2), ("tom", 1), ("shuke", 2))) //cogroup val rdd3 = rdd1.cogroup(rdd2) //注意cogroup與groupByKey的區別 rdd3.collect
val rdd1 = sc.parallelize(List(1, 2, 3, 4, 5)) //reduce聚合 val rdd2 = rdd1.reduce(_ + _)
//按value的降序排序 val rdd5 = rdd4.map(t => (t._2, t._1)).sortByKey(false).map(t => (t._2, t._1)) rdd5.collect //笛卡爾積 val rdd3 = rdd1.cartesian(rdd2) |
計算元素個數
scala> val rdd1 = sc.parallelize(List(2,3,1,5,7,3,4)) rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at parallelize at <console>:27
scala> rdd1.count res0: Long = 7 |
top先升序排序在取值
scala> rdd1.top(3) res1: Array[Int] = Array(7, 5, 4)
scala> rdd1.top(0) res2: Array[Int] = Array()
scala> rdd1.top(100) res3: Array[Int] = Array(7, 5, 4, 3, 3, 2, 1) |
take原集合前N個,有幾個取幾個
scala> rdd1.take(3) res4: Array[Int] = Array(2, 3, 1)
scala> rdd1.take(100) res5: Array[Int] = Array(2, 3, 1, 5, 7, 3, 4)
scala> rdd1.first res6: Int = 2 |
takeordered倒序排序再取值
scala> rdd1.takeOrdered(3) res7: Array[Int] = Array(1, 2, 3)
scala> rdd1.takeOrdered(30) res8: Array[Int] = Array(1, 2, 3, 3, 4, 5, 7) |
生成RDD的兩種方式
1.並行化方式生成 (預設分割槽兩個)
手動指定分割槽
scala> val rdd1 = sc.parallelize(List(1,2,3,5)) rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[5] at parallelize at <console>:27
scala> rdd1.partitions.length //獲取分割槽數 res9: Int = 2
scala> val rdd1 = sc.parallelize(List(1,2,3,5),3) rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[6] at parallelize at <console>:27
scala> rdd1.partitions.length res10: Int = 3 |
2.使用textFile讀取檔案儲存系統裡的資料
scala> val rdd2 = sc.textFile("hdfs://hadoop01:9000/wordcount/input/a.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_) rdd2: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[11] at reduceByKey at <console>:27
scala> rdd2.collect //呼叫運算元得到RDD顯示結果 res11: Array[(String, Int)] = Array((hello,6), (beijing,1), (java,1), (gp1808,1), (world,1), (good,1), (qianfeng,1))
scala> val rdd2 = sc.textFile("hdfs://hadoop01:9000/wordcount/input/a.txt",4).flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_) rdd2: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[26] at reduceByKey at <console>:27
scala> rdd2.partitions.length //也可以自己指定分割槽數 res15: Int = 4 |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2654461/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師分享乾貨 彈性分散式資料集RDD程式設計師分散式
- 好程式設計師大資料學習路線分享UDF函式程式設計師大資料函式
- 好程式設計師大資料學習路線分享Lambda表示式程式設計師大資料
- 好程式設計師大資料學習路線分享MAPREDUCE程式設計師大資料
- 好程式設計師大資料學習路線分享SparkSQl程式設計師大資料SparkSQL
- 好程式設計師大資料學習路線分享分散式檔案系統HDFS程式設計師大資料分散式
- 好程式設計師大資料學習路線分享大資料之字串程式設計師大資料字串
- 好程式設計師大資料學習路線分享高階函式程式設計師大資料函式
- 好程式設計師大資料學習路線分享Hbase指令學習程式設計師大資料
- 好程式設計師大資料學習路線分享大資料之執行緒程式設計師大資料執行緒
- 好程式設計師大資料學習路線分享HDFS讀流程程式設計師大資料
- 好程式設計師大資料學習路線分享AWK詳解程式設計師大資料
- 好程式設計師大資料學習路線分享spark之Scala程式設計師大資料Spark
- 好程式設計師大資料學習路線Hadoop學習乾貨分享程式設計師大資料Hadoop
- 好程式設計師大資料學習路線分享HDFS學習總結程式設計師大資料
- 好程式設計師大資料學習路線分享hdfs學習乾貨程式設計師大資料
- 好程式設計師大資料學習路線分享Actor學習筆記程式設計師大資料筆記
- 好程式設計師大資料學習路線分享Map學習筆記程式設計師大資料筆記
- 好程式設計師大資料培訓分享Hadoop分散式叢集程式設計師大資料Hadoop分散式
- 好程式設計師大資料學習路線分享函式+map對映+元祖程式設計師大資料函式
- 好程式設計師大資料學習路線分享大資料之基礎語法程式設計師大資料
- 好程式設計師大資料學習路線之大資料自學路線二程式設計師大資料
- 好程式設計師大資料學習路線之大資料自學路線一程式設計師大資料
- 好程式設計師大資料學習路線分享Scala系列之物件程式設計師大資料物件
- 好程式設計師大資料學習路線分享Hadoop機架感知程式設計師大資料Hadoop
- 好程式設計師大資料學習路線分享Scala系列之集合操作函式程式設計師大資料函式
- 好程式設計師大資料學習路線hive內部函式程式設計師大資料Hive函式
- 好程式設計師大資料學習路線分享TCP和UDP學習筆記程式設計師大資料TCPUDP筆記
- 好程式設計師大資料學習路線分享MapReduce全過程解析程式設計師大資料
- 好程式設計師大資料學習路線分享hive的執行方式程式設計師大資料Hive
- 好程式設計師大資料學習路線分享什麼是Hash表程式設計師大資料
- 好程式設計師大資料學習路線分享Scala系列之抽象類程式設計師大資料抽象
- 好程式設計師大資料學習路線分享Scala系列之陣列程式設計師大資料陣列
- 好程式設計師大資料學習路線分享Scala分支和迴圈程式設計師大資料
- 好程式設計師大資料學習路線分享MapReduce全流程總結程式設計師大資料
- 好程式設計師大資料學習路線分享Scala系列之泛型程式設計師大資料泛型
- 好程式設計師大資料學習路線Hbase總結程式設計師大資料
- 好程式設計師大資料學習路線之mapreduce概述程式設計師大資料