RDD到底是什麼?RDD的API
RDD到底是什麼?RDD的API
大家好,我是W
今天給大家帶來一篇關於Spark和RDD的部落格,由於我也是初學者,所以沒法帶來那麼深刻的東西,但是我希望用我的感性認知帶給大家一點靈感,畢竟剛開始學習Spark的時候我對RDD概念、Spark流程是有很多困惑的,我覺得大家也可能存在這種問題。OK,接下來我將從以下幾個角度來講RDD和Spark:1、 Spark簡介、對比hadoop、生態,2、 RDD概念
1、 Spark簡介、對比hadoop、生態
1.1 Spark簡介
在Spark官網,可以看到官方對Spark的概述:
Spark Overview
Apache Spark is a unified analytics engine for large-scale data processing. It provides high-level APIs in Java, Scala, Python and R, and an optimized engine that supports general execution graphs. It also supports a rich set of higher-level tools including Spark SQL for SQL and structured data processing, MLlib for machine learning, GraphX for graph processing, and Structured Streaming for incremental computation and stream processing.
Apache的Spark是一個用於大規模資料處理的統一分析引擎。它提供了一系列Java、Scaala、Python的高階API以及優化引擎,所以支援統一的操作。它同樣的提供了一系列豐富的高階工具,包括用於SQL查詢、結構化資料處理的Spark SQL,用於機器學習的MLlib庫,用於圖處理的GraphX庫,以及用於增量計算和流處理的Streaming庫。
可以看到官網對Spark的定義就是一個大一統的框架,其中存在做結構化資料處理的元件Spark SQL,有用於機器學習的MLlib元件等等。在我實際學習的過程中可以感覺到元件間的關係就好像積木一樣,需要的時候插上即可。
1.2 Spark對比Hadoop
Spark對比hadoop最大的特點就是快,在官網上第一張圖就擺出來Spark比hadoop快了百倍,Spark的運算是基於記憶體的,而hadoop則需要通過HDFS將資料持久化到磁碟,所以顯然是快的,但是快多少還是要看實際生產環境吧。
可是除了這點就沒了嗎?其實還有的,在《大資料基礎:Spark工作原理及基礎概念》中給大家羅列出來了:
特點 | 說明 |
---|---|
spark 計算速度快 | spark將每個任務構建成DAG進行計算,內部的計算過程通過彈性式分散式資料集RDD在記憶體在進行計算,相比於hadoop的mapreduce效率提升了100倍。 |
易於使用 | spark 提供了大量的運算元,開發只需呼叫相關api進行實現無法關注底層的實現原理。相較於以前離線任務採用mapreduce實現,實時任務採用storm實現,目前這些都可以通過spark來實現,降低來開發的成本。同時spark 通過spark SQL降低了使用者的學習使用門檻,還提供了機器學習,圖計算引擎等。 |
支援多種的資源管理模式 | 學習使用中可以採用local 模型進行任務的除錯,在正式環境中又提供了standalone,yarn等模式,方便使用者選擇合適的資源管理模式進行適配。 |
社群支援 | spark 生態圈豐富,迭代更新快,成為大資料領域必備的計算引擎。 |
1.3 Spark生態圈
其實剛剛介紹Spark的時候已經講了一點了,大家請看圖:
這是我找到比較合理的一張圖,它把不同的工作內容分層,結構比較清晰。
層 | 說明 |
---|---|
資源排程層 | 因為我們的任務是要提交到叢集上執行的,不同的結點有不同的工作,所以需要對計算資源進行排程,而在這一層的資源排程方式就有很多:local模式、StandAlone模式、yarn模式、mesos模式等等。 |
計算層 | 計算層主要使用的是spark-core這個spark的核心庫,其面向的是離線的計算,而R、Python這些就是所支援的語言。 |
儲存層 | 儲存層包括一系列的儲存元件,最常見的比如有hadoop-HDFS、MySQL、HBASE、MongoDB、Redis等等,這些均是spark生態可以對接的儲存元件,而右邊的sparkSQL顯然是支援這些資料來源的,而下方的MLlib等等顯然需要資料的支援。 |
資料流 | 在做實時計算的時候streaming可以對接flume、kafka等元件。 |
2、 RDD的概念(RDD到底是什麼)、Spark的工作流程
這兩個話題涉及了很多因素,我感覺這一篇文章還是不可能講的很清楚,但是我會用我能做到的最樸素的語言給大家感性的講一講。同時,我建議大家多做幾個小案例來加深認識。
2.1 RDD的概念
2.1.1 官方的定義
RDD是Spark中最重要的概念,其全稱叫做Resilient Distributed Dataset (RDD),即彈性分散式資料集,是一種可容錯的、可以被並行操作的元素集合,是Spark中處理所有資料的一種基本抽象。
光是看這一句還是不夠的,我在原始碼中找來註釋給大家看一下,我建議大家仔細看下原始碼的註釋:
/**
* A Resilient Distributed Dataset (RDD), the basic abstraction in Spark. Represents an immutable,
* partitioned collection of elements that can be operated on in parallel. This class contains the
* basic operations available on all RDDs, such as `map`, `filter`, and `persist`.
* 一個彈性分散式資料集(RDD),是Spark裡的基本抽象。
* 它代表了可以被並行操作的不可變的分割槽元素集合。這個類包含了各種RDD都支援的基本操作,比如map、filter、persist等。
*
* In addition,[[org.apache.spark.rdd.PairRDDFunctions]] contains operations available only on RDDs of key-value pairs, such as `groupByKey` and `join`;
* 此外,org.apache.spark.rdd.PairRDDFunctions裡還包含了只有鍵值對(key-value)型別RDD可用的操作,比如groupByKey、join等。
*
* [[org.apache.spark.rdd.DoubleRDDFunctions]] contains operations available only on RDDs of Doubles;
* org.apache.spark.rdd.DoubleRDDFunctions 裡包含了只有Double資料型別的RDD可用的操作。
*
* and [[org.apache.spark.rdd.SequenceFileRDDFunctions]] contains operations available on RDDs that can be saved as SequenceFiles.
* org.apache.spark.rdd.SequenceFileRDDFunctions 裡包含了可以被序列化成檔案的RDD所包含的操作。
*
* All operations are automatically available on any RDD of the right type (e.g. RDD[(Int, Int)] through implicit.
* 所有的操作都可以通過implicit來賦予。
*
* Internally, each RDD is characterized by five main properties:
* 在RDD內部,每一個RDD都由這五個主要特徵來描述:
*
* - A list of partitions
* - 一系列分割槽
*
* - A function for computing each split
* - 對每一個分片做計算的函式
*
* - A list of dependencies on other RDDs
* - 一系列對其他RDD的依賴
*
* - Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)
* - 視情況而定,一個作用於鍵值對RDD的分割槽器
*
* - Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file)
* - 視情況而定, 要計算每個分片的首選位置的列表
*
* All of the scheduling and execution in Spark is done based on these methods, allowing each RDD
* to implement its own way of computing itself. Indeed, users can implement custom RDDs (e.g. for
* reading data from a new storage system) by overriding these functions. Please refer to the
* <a href="http://people.csail.mit.edu/matei/papers/2012/nsdi_spark.pdf">Spark paper</a>
* for more details on RDD internals.
* Spark裡的所有scheduling和execution都是基於這些方法(通過賦予RDD操作的方式)來實現其自身的計算方式,當然使用者可以通過重寫方法自定義RDD。
*/
最後註釋中還貼心的給出了RDD的提出的論文:《Resilient Distributed Datasets: A Fault-Tolerant Abstraction for In-Memory Cluster Computing》。
RDD的操作分為兩大類,Transformation、Action。
Transformation是對已有的RDD進行轉換(記錄下一步操作)然後生成新的RDD,採用的是lazy策略,不會立即計算出結果。
Action是讓已有的RDD對資料執行它的操作。
表格來自:大資料之Spark簡介及RDD說明
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, Interator[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) | — |
Action
方法(運算元) | 說明 |
---|---|
reduce(func) | 通過func函式聚集RDD中的所有元素,這個功能必須是課交換且可並聯的 |
collect() | 在驅動程式中,以陣列的形式返回資料集的所有元素 |
count() | 返回RDD的元素個數 |
first() | 返回RDD的第一個元素(類似於take(1)) |
take(n) | 返回一個由資料集的前n個元素組成的陣列 |
takeSample(withReplacement,num, [seed]) | 返回一個陣列,該陣列由從資料集中隨機取樣的num個元素組成,可以選擇是否用隨機數替換不足的部分,seed用於指定隨機數生成器種子 |
takeOrdered(n, [ordering]) | — |
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進行更新。 |
2.1.2 我的感性認識
剛開始我對RDD也是很迷惑,它是在哪裡體現了並行化計算的?但是當我真正正正做一個完整的案例時,我才對他有那麼一點理解。
大家可以想一個完整的離線計算案例,比如:
我們需要計算美團上外賣的標籤,那麼我們會有類似以下資料集:
商品ID | 使用者ID | 評價(String) |
---|---|---|
109283 | yyyyxxx | 味道還不錯,就是有點貴 |
109283 | swssim | 雖然有點貴,但是分量足 |
… | … | … |
109284 | swssim | 好難吃! |
我們的目標是針對商品做標籤,依據是商品出現最多的5個評價標籤。
- 1、 首先我們通過sparkContext讀取資料
- 2、 因為我們拿到的是評價String,所以做分詞,這裡假設分詞調包成功,評價此時不再是一個長長的話,而是:評價1,評價2
- 3、 接下來,提取出商品ID,評價
- 4、 根據商品ID聚類,即groupByKey
- 5、 對後面標籤做操作…
- …
請大家注意第3步,我們的程式放到叢集中,而叢集中顯然不止一臺worker,即顯然不止一個executor,所以我們整個spark叢集中每一個executor拿到的只是整個資料集的一部分(第一臺拿0 - n-1行,第二臺拿n - 2n-1行類似這樣),但是我們的操作是寫在一份程式裡面,如何對不同機器中的資料集做統一的操作呢?
這顯然就是RDD的作用,程式提交時會經過cluster manager分配資源、通過driver提交程式碼到executor,然後經過各種scheduler把程式進行分析,分成多個stage,每一個stage代表了不需要跨機器執行的操作的集合(比如map、filter),而當出現要跨機器操作(比如collect、reduce)時,則會把資料集中到一臺機器去操作。
說了那麼多,RDD到底是什麼呢?
解釋1 : 因為每一臺機器都知道哪幾步本機器不需要依靠別人可以自己做(stage),所以可以先做,不需要看別人臉色,而遇到大家統一的操作時通過網路把資料合併由一臺機器做。RDD就是定義這些操作的物件,RDD操作的物件就是分佈在不同機器上的同一格式的資料集。
解釋2 : 資料集分佈在不同機器中,RDD定義了各個機器對這份資料的同一操作(先做什麼再做什麼)。就好像你安排你的小弟,去不同銀行,插入銀行卡,輸入密碼,取5000塊錢,然後拿回來,最後給你彙總一樣。
參考
總結
Spark毫無疑問是個非常優秀的框架,其中的元件就彷彿積木一般隨時插拔。RDD作為Spark的最重要的概念,對Spark整個框架起著至關重要的作用。RDD的操作分為Transoformation和Action兩種,其核心理念是定義一個抽象的資料操作,從而方便每個分割槽針對各自所管理的資料做統一的操作。今天這篇部落格可能還有很多沒法講清楚的地方,接下來我會繼續把Spark的其他概念、RDD涉及的相關概念更詳細的給大家理清楚。
相關文章
- Spark RDD APISparkAPI
- Spark RDD使用詳解--RDD原理Spark
- RDD的快取快取
- spark-RDDSpark
- Spark筆記:複雜RDD的API的理解(下)Spark筆記API
- RDD持久化,不使用RDD持久化的問題的工作原理持久化
- Spark 的核心概念 RDDSpark
- RDD程式設計程式設計
- Spark - [03] RDD概述Spark
- Spark Basic RDD 操作示例Spark
- RDD的詳解、建立及其操作
- RDD、DataFrame和DataSet的區別
- Spark RDD詳解 | RDD特性、lineage、快取、checkpoint、依賴關係Spark快取
- SparkSQL /DataFrame /Spark RDD誰快?SparkSQL
- Spark RDD 特徵及其依賴Spark特徵
- SparkCore-RDD持久化操作Spark持久化
- spark學習筆記--RDDSpark筆記
- 大白話講解Spark中的RDDSpark
- Calcite 使用原生的RDD 處理SparkSpark
- Spark學習(二)——RDD基礎Spark
- 【大資料】Spark RDD基礎大資料Spark
- spark RDD,reduceByKey vs groupByKeySpark
- Spark RDD中Runtime流程解析Spark
- spark常用RDD介紹及DemoSpark
- Spark SQL中的RDD與DataFrame轉換SparkSQL
- Spark從入門到放棄---RDDSpark
- 快取Apache Spark RDD - 效能調優快取ApacheSpark
- RDD程式設計 上(Spark自學三)程式設計Spark
- RDD程式設計 下(Spark自學四)程式設計Spark
- Spark開發-RDD介面程式設計Spark程式設計
- Spark RDD的預設分割槽數:(spark 2.1.0)Spark
- Spark RDD在Spark中的地位和作用如何?Spark
- spark: RDD與DataFrame之間的相互轉換Spark
- 大資料學習—Spark核心概念RDD大資料Spark
- Spark----RDD運算元分類 DAGSpark
- Spark開發-RDD分割槽重新劃分Spark
- Spark開發-spark執行原理和RDDSpark
- spark學習筆記--RDD鍵對操作Spark筆記