[英]What are the differences between Dataframe, Dataset, and RDD in Apache Spark?
在 Apache Spark 中,這些 API 之間有什么區別? 為什么以及何時我們應該選擇其中一個而不是其他?
首先,讓我們定義 spark 的作用
簡單地說,它所做的就是對分布式數據執行操作。 因此,操作也需要分布。 有些操作很簡單,例如過濾掉所有不遵守某些規則的項目。 其他更復雜,例如需要移動數據的 groupBy 和需要關聯來自 2 個或更多數據集的項目的 join。
另一個重要的事實是輸入和輸出以不同的格式存儲,spark 具有讀取和寫入這些的連接器。 但這意味着對它們進行序列化和反序列化。 雖然是透明的,但序列化通常是最昂貴的操作。
最后,spark 嘗試將數據保留在內存中以供處理,但當它不適合內存時,它會在每個工作人員本地 [ser/deser]ialize 數據。 再一次,它是透明地完成的,但成本可能很高。 有趣的事實:估計數據大小可能需要時間
API
這是 spark 提供的第一個 API。 簡單地說,它是分布在集群上的 scala/java 對象的無序序列。 在其上執行的所有操作都是 jvm 方法(傳遞給 map、flatmap、groupBy、...),這些方法需要被序列化,發送給所有工作人員,並應用於那里的 jvm 對象。 這與使用 scala Seq 幾乎相同,但是是分布式的。 它是強類型的,這意味着“如果它編譯然后它工作”(如果你不作弊)。 但是,可能會出現許多分發問題。 特別是如果 spark 不知道如何 [反] 序列化 jvm 類和方法。
它緊隨其后,在語義上與 RDD 非常不同。 數據被視為表,可以對其進行sql操作等操作。 它根本沒有輸入,因此在執行過程中隨時可能出現錯誤。 但是,我認為有 2 個優點:(1)很多人習慣於 table/sql 語義和操作,(2)spark 不需要反序列化整行來處理它的列之一,如果數據格式提供合適的列訪問。 很多都這樣做,例如最常用的 parquet 文件格式。
這是對 Dataframe 的改進,帶來了一些類型安全。 數據集是我們將與 jvm 類相關的“編碼器”關聯到的數據幀。 所以spark可以在執行代碼之前檢查數據模式是否正確。 但是請注意,有時我們可以讀到數據集是強類型的,但事實並非如此:它帶來了一些強類型安全性,您無法編譯使用具有未聲明類型的數據集的代碼。 但是很容易編寫可以編譯但在運行時仍然失敗的代碼。 這是因為許多數據集操作會丟失類型(除了過濾器之外的幾乎所有內容)。 這仍然是一個巨大的改進,因為即使我們犯了錯誤,它也會很快失敗:失敗發生在解釋 spark DAG 時(即在開始時)而不是在數據處理期間。
注意:數據框現在只是無類型的數據集( Dataset<Row>
)
注2:Dataset提供了RDD的主要API,如map、flatMap等。 據我所知,轉換為 rdd,然后應用 map/flatMap,然后轉換為數據集是一種捷徑。 這很實用,但也隱藏了轉換,因此很難意識到發生了可能代價高昂的 ser/deserialization。
優點和缺點
數據集:
數據框:
RDD:
結論
只需默認使用數據集:
在某些情況下,您要編碼的內容過於復雜而無法使用數據集操作來表達。 大多數應用程序沒有,但它經常發生在我實現復雜數學模型的工作中。 在這種情況下:
簡而言之:
我使用數據幀並強烈推薦它們:Spark 的優化器 Catalyst 可以理解更好的數據集(以及數據幀),並且 Row 是比純 JVM 對象更好的存儲容器。 你會發現很多關於內部的博客文章(包括 Databricks')。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.