> For the complete documentation index, see [llms.txt](https://spark-nctu.gitbook.io/spark/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://spark-nctu.gitbook.io/spark/rdd-cao-zuo/resilient-distributed-dataset-rdd.md).

# Resilient Distributed Dataset (RDD)

## 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()` 查看。<br>

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

![來自: https://stackoverflow.com/questions/39311616/transformation-process-in-apache-spark](/files/-LPzs_L07wlu53z0pg6D)

簡單來說，經過 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
```

`count` 和 `first` 都是一個 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 比較適合用於暫存變數，並要特別注意在平行計算時的處理
