RDD vs. DataFrame vs. DataSet

新的 Spark 資料型態: DataFrame 和 DataSet

作為一個新興的平行運算平台,Spark 如宿命般在穩定以及效率兩端徘迴。RDD 這個原本 Spark 設計的核心概念,在 Spark 3.0 之後將進入冷凍 (maintenance mode)。在未來,新的 API 開發將基於新的 DataFrame 資料型態。因此,我們將先來探索這些新興的資料型態,並嘗試了解,為什麼 Spark 要做出這樣的變革。

RDD vs. DataFrame vs. DataSet

我們先來看看 RDD 和 DataFrame 的差別。

DataFrame 是由 schemeRDD 型態衍生而來,簡單來說,就是一種有資料格式的 RDD。因此,和 RDD 一樣,可以視為一組不可變分散式資料元素集合。然而,和 RDD 不同,DataFrame 必須定義其資料格式,比較像是一個 SQL 的表格,我們可以以下圖表示:

上圖的 DataFrame 定義了各欄位 (Column) 的意義,因此,可以方便我們做更抽象的資料處理。而對於 RDD 而言,每一個 Person 物件並沒有格式化,而每一列 (Row) 的資料則分散儲存於各節點。這樣的一組分散式資料,可以進行上述的 Action 和 Transformation 運算。

事實上,上圖的 DataFrame 由於定義了各欄位的資料格式,更接近於 DataSet 的概念。對於 DataFrame 而言,可以視為是 untypied DataSet,也就是說,定義了例如像是 Age 的欄位,卻沒有定義 Age 的型態,而要到處理時才會決定型態。對於程式語言而言,這樣的屬性稱為 dynamically typed,代表像是: Python、matlab、R 等。另一方面,DataSet 這種預先定義好資料型態的方法,稱為 statically typed,我們可以在像是 Java、C、Scala (Java-based) 中看到此類語言的特性。

簡單來說,statically typed 更加安全,可以在編譯階段就找到錯誤,dynamically typed 的語言則可以進行抽象的語言操作,讓程式簡潔而易懂,我可以把比較列下表。

考慮到程式語言的特性,顯然的,Python 無法支援 DataSet API。

從 RDD 到 DataFrame

在 Spark 3.0 中,RDD-based 的 API 要停止更新,而主要支援 DataFrame-based 的 API。但是,這並不代表 RDD 這種資料型態將從 Spark 中消失。事實上,不論是 DataFrame 還是 DataSet 都是基於 RDD 的架構完成,RDD 仍然是最基礎的 Spark 資料型態,也是 Spark 可以提供平行化的設計。我們可以從下圖中看到,DataFrame 和 DataSet 實際上是透過 Catalyst 來建立 RDD。

Catalyst Optimizer 是 Spark SQL 中建立的一個模組,提供基於查詢與運算優化 RDD 配置的一個最佳化工具。換句話說,我們所宣告的 DataFrame 和 DataSet 將根據我們對其處理的動作,在 Spark 底層轉化成 RDD。

此時,出現一個有趣的問題: 為什麼直接操作 RDD,會比較沒有效率?而透過 DataFrame 或是 DataSet 的抽象操作反而更有效率呢?這是因為當我們直接操作 RDD 時,會傾向重複宣告 RDD,或是對一個大型的 RDD 進行操作,而不是真的對需要的資料進行操作。

Last updated