spark02--RDD概念,屬性,類型,32個常用算子,創建,reduceByKey和groupByKey的區別

一 彈性分佈式數據集(RDD)

RDD是一個分佈式數據集, 是spark中最基本的數據抽象, 是一個不可變, 可分區, 裏面的元素可以並行計算集合, 具有高容錯, 位置感知性調度, 可伸縮性的特點

1.1 高容錯

RDD的容錯性其實就是爲了提高計算效率, 如果在shuffle前發生宕機, 只需要把丟失的分區對應的父RDD分區進行重新計算即可, 如果是shuffle後的分區數據丟失, 此時就需要將整個父RDD的分區調用shuffle算子進行重新計算
RDD的容錯性就是指RDD分區的恢復過程, 和Worker宕機無關
在這裏插入圖片描述

1.2 位置感知性調度

位置感知就是把具體的計算邏輯發送到對應的數據節點上, 進行計算, 可以有效避免發生大量網絡IO
在這裏插入圖片描述

如果Worker節點和datanode節點不是一個幾點的話, 這個時候Worker會從datanode節點上拉取數據
在這裏插入圖片描述

如果工作的Worker節點發生了宕機, 這個時候不會重新開啓一個worker, 而是會將宕機的那個節點所執行的任務分配到另一個worker上
在這裏插入圖片描述

1.3 可伸縮性

RDD可以實現自動容錯

二 RDD的屬性

  • A list of partitions
  • A function for computing each split
  • A list of dependencies on other RDDs
  • Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)
  • Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file)

1)一組分片(Partition),即數據集的基本組成單位。對於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類型

官網鏈接: https://spark.apache.org/docs/2.2.0/rdd-programming-guide.html#basics

  • 帶有By的算子都是發生在shuffle過程

3.1 Transformation

特點: 延遲加載
常用的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) 對源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,Iterable))類型的RDD
cartesian(otherDataset) 笛卡爾積
pipe(command, [envVars])
coalesce(numPartitions) 重新分區
repartition(numPartitions) 重新分區
repartitionAndSortWithinPartitions(partitioner) 重新分區

3.2 Action

  • 立即運行
  • 在源碼中Action算子會調用 runJob 方法
  • 每調用一個action算子就相當於提交了一個Job
動作 含義
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方式三種方式

1)由一個已經存在的Scala集合創建。
sc.parallelize(Array(1,2,3,4))
2)由外部存儲系統的數據集創建,包括本地的文件系統,還有所有Hadoop支持的數據集,比如HDFS、Cassandra、HBase等
sc.textFile("hdfs://hadoop:8020/word.txt")
3)使用makeRDD函數創建
sc.makeRDD(Array(1,2,3,4))

五 reduceByKey和groupBykey的區別

reduceByKey會先進行局部聚合, 再進行全局聚合, 這樣會大大減少網絡IO, 起到優化作用, 所以在能用到reduceByKey的情況下用reduceByKey
groupByKey
在這裏插入圖片描述

reduceByKey
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章