天天看點

Spark SQL、DataFrame、DataSet是什麼

作者:新知大佬

在很多情況下,開發人員并不了解Scala語言,也不了解Spark常用的API,但又非常想要使用Spark架構提供的強大的資料分析能力。Spark的開發工程師們考慮到了這個問題,于是利用SQL語言的文法簡潔、學習門檻低以及在程式設計語言中普及程度和流行程度高等諸多優勢,開發了Spark SQL子產品。通過Spark SQL,開發人員能夠使用SQL語句實作對結構化資料的處理。

本節主要介紹什麼是Spark SQL、Spark SQL的特點、什麼是DataFrame和什麼是DataSet。

4.1.1 什麼是Spark SQL

Spark SQL是Spark用于結構化資料(Structured Data)處理的Spark子產品。與基本的Spark RDD API不同,Spark SQL的抽象資料類型為Spark提供了關于資料結構和正在執行的計算的更多資訊。在内部,Spark SQL使用這些額外的資訊去做一些優化。

有多種方式與Spark SQL進行互動,比如SQL和Dataset API。當計算結果的時候,這些接口使用相同的執行引擎,不依賴正在使用哪種API或者語言。這種統一也就意味着開發者可以很容易在不同的API之間進行切換,這些API提供了最自然的方式來表達給定的轉換。

Hive是将Hive SQL轉換成MapReduce,然後送出到叢集上執行,大大簡化了編寫MapReduce程式的複雜性,但是MapReduce這種計算模型執行效率比較慢,是以Spark SQL應運而生,它将Spark SQL轉換成RDD,然後送出到叢集上執行,執行效率非常高。

Spark SQL提供了以下2個程式設計抽象,類似Spark Core中的RDD。

l DataFrame。

l DataSet。

4.1.1 Spark SQL的特點

(1)Integrated(易整合):Spark SQL無縫地整合了SQL查詢和Spark程式設計。

(2)Uniform Data Access(統一的資料通路方式):Spark SQL使用相同的方式連接配接不同的資料源。

(3)Hive Integration(內建 Hive):Spark SQL在已有的倉庫上直接運作SQL或者HiveQL。

(4)Standard Connectivity(标準的連接配接方式):Spark SQL通過JDBC或者ODBC來連接配接。

4.1.3 什麼是DataFrame

與RDD類似,DataFrame也是一個分布式資料容器。

然而DataFrame更像傳統資料庫的二維表格,除了資料以外,還記錄資料的結構資訊,即schema。

同時,DataFrame與Hive類似,也支援嵌套資料類型(struct、array和map)。

從API易用性的角度上看,DataFrame API提供的是一套高層的關系操作,比函數式的RDD API要更加友好、門檻更低。

DataFrame與RDD的差別如圖4-5所示。

Spark SQL、DataFrame、DataSet是什麼

圖4-5

圖中左側的RDD[Person]雖然以Person為類型參數,但Spark架構本身不了解Person類的内部結構。而右側的DataFrame卻提供了詳細的結構資訊,使得Spark SQL可以清楚地知道該資料集中包含哪些列,每列的名稱和類型各是什麼。

DataFrame為資料提供了schema視圖,可以把它當作資料庫中的一張表來對待。

DataFrame也是懶執行的,性能上比RDD要高,主要原因在于優化的執行計劃—查詢計劃通過Spark Catalyst Optimiser(Catalyst優化器,基于Scala的函數式程式設計結構設計的可擴充優化器)進行優化。

為了說明查詢優化,我們來看圖4-6展示的人口資料分析的示例。

Spark SQL、DataFrame、DataSet是什麼

圖4-6

圖中構造了兩個DataFrame,将它們join之後又做了一次filter操作。

如果原封不動地執行這個計劃,最終的執行效率不是很高,因為join是一個代價較大的操作,也可能會産生一個較大的資料集。如果我們能将filter下推到join下方,先對DataFrame進行過濾,再join過濾後的較小的結果集,便可以有效縮短執行時間。而Spark SQL的查詢優化器正是這樣做的。簡而言之,邏輯查詢計劃優化就是一個利用基于關系代數的等價變換,将高成本操作替換為低成本操作的過程。

4.1.4 什麼是DataSet

(1)DataSet是DataFrame API的一個擴充,也是Spark SQL最新的資料抽象(1.6版本新增)。

(2)使用者友好的API風格,既具有類型安全檢查,也具有DataFrame的查詢優化特性。

(3)Dataset支援編解碼器,當需要通路非堆上的資料時可以避免反序列化整個對象,提高了效率。

(4)樣例類被用來在DataSet中定義資料的結構資訊,樣例類中每個屬性的名稱直接映射到DataSet中的字段名稱。

(5)DataFrame是DataSet的特列,DataFrame=DataSet[Row],是以可以通過as方法将DataFrame轉換為DataSet。Row是一個類型,跟Car、Person這些類型一樣,所有的表結構資訊都用Row來表示。

(6)DataSet是強類型的,比如可以有DataSet[Car]、DataSet[Person]等。

(7)DataFrame隻是知道字段,但是不知道字段的類型,是以在執行這些操作時是沒辦法在編譯的時候檢查字段類型是否正确,比如我們對一個字元串進行減法操作,在執行的時候才報錯。而DataSet不僅知道字段,還知道字段類型,是以有更嚴格的錯誤檢查。

本文摘自《Spark入門與大資料分析實戰》,獲出版社和作者授權釋出。

繼續閱讀