Resilient Distributed Dataset (RDD)

Spark 中的基本資料型態

RDD 的基本概念

在 Spark 中,資料的基本架構為 RDD (Resilient Distributed Dataset),RDDs 可以使用 Hadoop InputFormats (例如 HDFS 文件) 創建,也可以從其他的 RDDs 轉換。我們可以簡單的從一個文字檔建立 RDD, 例如:

scala> val textFile = sc.textFile("README.md")

基本上,就是從文字檔中建立一個 RDD 物件,此時,該 RDD 物件已經轉換成 string array 的格式,可以透過: scala> textFile.collect() 查看。

RDD 仍保有 HDFS 的特性,也就是 key-value 的格式,在 textFile 這個 RDD 中, key 就是第幾行, value 則是每行的數值,對於所有的 RDD, 我們都有兩種操作: action 和 transformation (請參考連結),RDD 的 actions 從 RDD 中返回值,transformations 可以轉換成一個新 RDD 並返回它的引用。如下圖表示:

簡單來說,經過 transformation 後的 RDD,仍然保有和原本 RDD 相同的 key-value 的形式,而經過 action 運算之後, key-value 的形式則和原本 RDD 不同。 舉例來說:

scala> val linesWithSpark = textFile.filter(line => line.contains("Spark"))

其中,filter是一個 transformation 運算,雖然新產生的 RDD (linesWithSpark) 行數較少,但仍然是 string array 的格式。

scala> textFile.count() // RDD 的數據行數
res0: Long = 126
scala> textFile.first() // RDD 的第一行數據
res1: String = # Apache Spark

countfirst 都是一個 action 運算,此時, RDD 的格式變成 long 和 string, 而不是 string array 的格式。 透過 transformation 和 action,我們就可以開始設計平行計算架構,在官方的介紹中,也說明了 map-reduce 架構的範例:

https://taiwansparkusergroup.gitbooks.io/spark-programming-guide-zh-tw/content/quick-start/using-spark-shell.html

兩種資料型態: val 和 var

在 Spark 中有兩種資料型態: val 和 var,其中,val 為唯讀的 RDD,而 var 則可以供我們進行一般的運算。舉例來說:

scala> val foo = 1
foo: Int = 1
scala> var bar = 1
bar: Int = 1
scala> bar = 2
bar: Int = 2
scala> foo = 2
<console>:25: error: reassignment to val
       foo = 2
           ^

可以看到,宣告為 val 的參數 (foo) 無法改變,但是,作為 var 的參數 (bar) 可以被改變。在 Spark 中,val 和 var 都是 RDD,然而,考慮到平行運算的特性,在 Spark 程式中應該養成以 val 為主的習慣。

在平行計算中,若是一參數是可變的 (如: var),則原本程式間的時序性將會出現問題 (其他平行的處理緒也可以更改其值),因此,val 可以確保 Spark 在平行計算時的一致性。 總而言之,在 Spark 程式中,為了善用其運算特性,應該要好好設計資料結構, 多用 val 以及 Action 和 Transformation 來處理,var 比較適合用於暫存變數,並要特別注意在平行計算時的處理

Last updated