Spark中RDD、DataFrame和DataSet的區別


 

 

 

前言

最近同事開始學習使用Spark,問我RDD、DataFrame和DataSet之間有什么區別,以及生產環境中的spark1.6將在不久后被移除,全部使用spark2+。於是今天我就借機整理了以下它們三者之間的異同。

RDD、DataFrame和DataSet的定義

在開始Spark RDD與DataFrame與Dataset之間的比較之前,先讓我們看一下Spark中的RDD,DataFrame和Datasets的定義:

  • Spark RDD
    RDD代表彈性分布式數據集。它是記錄的只讀分區集合。 RDD是Spark的基本數據結構。它允許程序員以容錯方式在大型集群上執行內存計算。
  • Spark Dataframe
    與RDD不同,數據組以列的形式組織起來,類似於關系數據庫中的表。它是一個不可變的分布式數據集合。 Spark中的DataFrame允許開發人員將數據結構(類型)加到分布式數據集合上,從而實現更高級別的抽象。
  • Spark Dataset
    Apache Spark中的Dataset是DataFrame API的擴展,它提供了類型安全(type-safe),面向對象(object-oriented)的編程接口。 Dataset利用Catalyst optimizer可以讓用戶通過類似於sql的表達式對數據進行查詢。

RDD、DataFrame和DataSet的比較

Spark版本
  • RDD – 自Spark 1.0起
  • DataFrames – 自Spark 1.3起
  • DataSet – 自Spark 1.6起
數據表示形式
  • RDD
    RDD是分布在集群中許多機器上的數據元素的分布式集合。 RDD是一組表示數據的Java或Scala對象。
  • DataFrame
    DataFrame是命名列構成的分布式數據集合。 它在概念上類似於關系數據庫中的表。
  • Dataset
    它是DataFrame API的擴展,提供RDD API的類型安全,面向對象的編程接口以及Catalyst查詢優化器的性能優勢和DataFrame API的堆外存儲機制的功能。
數據格式
  • RDD
    它可以輕松有效地處理結構化和非結構化的數據。 和Dataframe和DataSet一樣,RDD不會推斷出所獲取的數據的結構類型,需要用戶來指定它。
  • DataFrame
    僅適用於結構化和半結構化數據。 它的數據以命名列的形式組織起來。
  • DataSet
    它也可以有效地處理結構化和非結構化數據。 它表示行(row)的JVM對象或行對象集合形式的數據。 它通過編碼器以表格形式(tabular forms)表示。
編譯時類型安全
  • RDD
    RDD提供了一種熟悉的面向對象編程風格,具有編譯時類型安全性。
  • DataFrame
    如果您嘗試訪問表中不存在的列,則持編譯錯誤。 它僅在運行時檢測屬性錯誤。
  • DataSet
    DataSet可以在編譯時檢查類型, 它提供編譯時類型安全性。
    [TO-DO 什么是編譯時的類型安全]
序列化
  • RDD
    每當Spark需要在集群內分發數據或將數據寫入磁盤時,它就會使用Java序列化。序列化單個Java和Scala對象的開銷很昂貴,並且需要在節點之間發送數據和結構。

  • DataFrame
    Spark DataFrame可以將數據序列化為二進制格式的堆外存儲(在內存中),然后直接在此堆內存上執行許多轉換。無需使用java序列化來編碼數據。它提供了一個Tungsten物理執行后端,來管理內存並動態生成字節碼以進行表達式評估。

  • DataSet
    在序列化數據時,Spark中的數據集API具有編碼器的概念,該編碼器處理JVM對象與表格表示之間的轉換。它使用spark內部Tungsten二進制格式存儲表格表示。數據集允許對序列化數據執行操作並改善內存使用。它允許按需訪問單個屬性,而不會消滅整個對象。

垃圾回收
  • RDD
    創建和銷毀單個對象會導致垃圾回收。
  • DataFrame
    避免在為數據集中的每一行構造單個對象時引起的垃圾回收。
  • DataSet
    因為序列化是通過Tungsten進行的,它使用了off heap數據序列化,不需要垃圾回收器來摧毀對象
效率/內存使用
  • RDD
    在java和scala對象上單獨執行序列化時,效率會降低,這需要花費大量時間。
  • DataFrame
    使用off heap內存進行序列化可以減少開銷。 它動態生成字節代碼,以便可以對該序列化數據執行許多操作。 無需對小型操作進行反序列化。
  • DataSet
    它允許對序列化數據執行操作並改善內存使用。 因此,它可以允許按需訪問單個屬性,而無需反序列化整個對象。
編程語言支持
  • RDD
    RDD提供Java,Scala,Python和R語言的API。 因此,此功能為開發人員提供了靈活性。
  • DataFrame
    DataFrame同樣也提供Java,Scala,Python和R語言的API
  • DataSet
    Dataset 的一些API目前僅支持Scala和Java,對Python和R語言的API在陸續開發中
聚合操作(Aggregation)
  • RDD
    RDD API執行簡單的分組和聚合操作的速度較慢。
  • DataFrame
    DataFrame API非常易於使用。 探索性分析更快,在大型數據集上創建匯總統計數據。
  • DataSet
    在Dataset中,對大量數據集執行聚合操作的速度更快。

結論

  • 當我們需要對數據集進行底層的轉換和操作時, 可以選擇使用RDD
  • 當我們需要高級抽象時,可以使用DataFrame和Dataset API。
  • 對於非結構化數據,例如媒體流或文本流,同樣可以使用DataFrame和Dataset API。
  • 我們可以使用DataFrame和Dataset 中的高級的方法。 例如,filter, maps, aggregation, sum, SQL queries以及通過列訪問數據等
    如果您不關心在按名稱或列處理或訪問數據屬性時強加架構(例如列式格式)。
    另外,如果我們想要在編譯時更高程度的類型安全性。

RDD提供更底層功能, DataFrame和Dataset則允許創建一些自定義的結構,擁有高級的特定操作,節省空間並高速執行。

為了確保我們的代碼能夠盡可能的利用Tungsten優化帶來的好處,推薦使用Scala的 Dataset API(而不是RDD API)。

Dataset即擁有DataFrame帶來的relational transformation的便捷,也擁有RDD中的functional transformation的優勢。

參考資料
apache-spark-rdd-vs-dataframe-vs-dataset

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM