# 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 比較適合用於暫存變數，並要特別注意在平行計算時的處理


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://spark-nctu.gitbook.io/spark/rdd-cao-zuo/resilient-distributed-dataset-rdd.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
