# Spark環境安裝教學

<!--more-->

## 前言

{{< admonition info >}}
本篇文章適用於入門級別的學習者。看完這篇之後，你將能夠獨立建置一套單機環境，並親手體驗 Apache Spark 的基本功能。筆者盡量把踩過的坑都寫進來，跟著步驟做，應該可以省下不少摸索時間。
{{< /admonition >}}

## Apache Spark 簡介

Apache Spark 是一個開源的分散式資料處理引擎，主要用於大規模資料分析、資料工程與機器學習工作流程。與傳統以單機為主的資料處理工具不同，Spark 能將大型資料集切分成多個任務，分配到不同節點（Node）同時執行，藉此提升資料處理效率與擴展能力。

Spark 最大的特色之一，是**記憶體內運算（In-Memory Computing）**。傳統資料處理框架常需要頻繁將中間結果寫入磁碟，而 Spark 可以把常用資料暫存在記憶體中，減少磁碟 I/O 操作。因此在需要多次迭代計算的情境（例如機器學習、互動式分析），Spark 能提供明顯更快的執行速度。

此外，Spark 採用**分散式運算模型（Distributed Computing Model）**，可以從單機環境一路擴展到大型叢集環境。開發者不需要親自處理底層的資料分割、任務分配與節點通訊，只要透過 Spark 提供的高階 API（如 DataFrame、SQL、RDD）描述資料處理邏輯，Spark 便會自動負責拆分工作並分配執行——這也是筆者認為它比早期 Hadoop 生態系友善很多的地方。

Spark 支援多種程式語言，包括 Scala、Python、Java 與 R，並提供 Spark SQL、Structured Streaming、MLlib 等模組，可應用於資料分析、即時串流處理、ETL Pipeline 以及機器學習等場景。

簡單來說，Apache Spark 可以視為一套「為大量資料設計的高速分散式計算平台」，透過記憶體運算與平行處理能力，讓資料工程師能有效處理傳統單機工具難以負荷的大型資料。

### Apache Spark 與常見資料處理工具比較

| 工具 | 主要定位 | 運算模式 | 記憶體處理 | 分散式能力 | 適合場景 |
|---|---|---|---|---|---|
| Apache Spark | 大規模分散式資料處理引擎 | 分散式平行運算 | ✅ 強（支援 Cache / Persist） | ✅ 原生支援 | Big Data ETL、資料分析、Machine Learning、Streaming |
| Pandas | Python 資料分析函式庫 | 單機運算 | ✅ 主要在 RAM | ❌ 不支援原生分散式 | 小中型資料分析、資料清理、探索分析 |
| Dask | Python 分散式資料分析框架 | 平行計算 | ✅ 支援記憶體運算 | ✅ 支援多節點 | Pandas 使用者處理較大型資料 |
| Polars | 高效能 DataFrame 函式庫 | 單機平行運算 | ✅ 主要在 RAM | ⚠️ 有分散式方案 | 高效能資料分析、取代 Pandas |
| Apache Hadoop MapReduce | 傳統大數據批次處理框架 | 磁碟式 MapReduce | ❌ 依賴 Disk I/O | ✅ 原生支援 | 大型批次資料處理 |
| Apache Flink | 即時串流處理平台 | 分散式串流計算 | ✅ 支援狀態管理 | ✅ 原生支援 | Real-time Streaming、事件處理 |

### 使用情境比較

| 使用情境 | 建議工具 |
|---|---|
| 小型資料分析、Notebook 探索 | Pandas / Polars |
| 大型 ETL Pipeline | Apache Spark |
| TB 等級資料處理 | Apache Spark / Hadoop |
| 即時事件流處理 | Apache Flink / Spark Structured Streaming |
| 機器學習資料前處理 | Apache Spark + MLlib |

{{< admonition note >}}
如果你手上的資料量還在幾 GB、單機記憶體吃得下，其實 Pandas 或 Polars 就綽綽有餘，不必為了「用大數據工具」而硬上 Spark。等資料規模真的超出單機負荷，再導入 Spark 也不遲。
{{< /admonition >}}

## 開始之前

在正式進入今天的主題之前，先準備好以下工具與版本。

### 版號

|  軟體   | 版本  |
|  ----  | ----  |
| Virtual Machine   | 7.1.4（或以上） |
| Redhat ISO   |  9.8 |
| Java openjdk   |  17.0 |
| Spark  |  4.2.0 |

### 虛擬機安裝
1. 本篇教學採用台灣業界最常見的虛擬機類型來安裝，[官方 ISO 下載連結](https://developers.redhat.com/products/rhel/download)（挑選最新版本的 boot ISO 下載即可）。
   ![下載映像檔](./download-iso.png)
2. 無論是下載映像檔，或後續要連接 Red Hat repo，都需要一組 Red Hat 帳號。可以到 [Developer 入口網站](https://developers.redhat.com/) 申請加入研發者計畫，該計畫可免費下載 RHEL（供個人開發、測試使用）。
3. 在 VirtualBox 安裝過程中看到以下畫面時，記得選擇 **Connect to Red Hat**。
   ![安裝介面](./install-iso.png)
4. 安裝完成後進入終端機，輸入以下指令確認鏡像倉庫是否正常連接：
    ~~~bash
    yum repolist -v
    ~~~
    只要沒有出現 error，看到類似下圖的回傳資訊，就代表連線成功。
    ![yum-repolist-v](./yum-repolist-v.png)

到這裡，一台可用的虛擬機就準備好了，接下來可以開始安裝 Spark 所需的套件。

## 安裝 Spark

進入 Apache Spark 官網下載現行版本（相依套件我們會依照啟動時跳出的錯誤訊息，再逐一補齊，不用一開始就求全）。

1. 到[官方網站](https://spark.apache.org/downloads.html)選擇最近期版本 *4.2.0*，以及 Pre-Built 套件。
   ![Apache-Spark 入口網站](./official-page.png)
2. 點選前一張圖片中的 download-spark 超連結，會進入下載頁。把紅框處的網址複製起來，回到虛擬機用 `wget` 下載：
    ~~~bash
    cd ~
    mkdir spark
    wget <spark.tgz 包網址>
    tar zxvf <spark.tgz 包>      # 解壓縮
    rm -rf <spark.tgz 包網址> && cd <spark 解壓縮包>
    ~~~

## 環境變數設定

1. 進入解壓縮包後，先嘗試啟動服務，會看到以下錯誤：
    ~~~bash
    cd <spark 解壓縮包>
    cd <spark 解壓縮包>/bin
    ./spark-shell      # 提示要設置 JAVA_HOME
    ~~~
    ![JAVA_HOME錯誤](./java-home.png)

    {{< admonition warning >}}
    這是新手最常卡關的地方：Spark 本身不含 JVM，啟動前一定要先確認 `JAVA_HOME` 有設對，而且版本要對得上 Spark 官方要求，不然就算裝了 Java，spark-shell 一樣起不來。
    {{< /admonition >}}

2. 到最新版的官方文件中，確認該版本對應的 Java 版本需求（[最新版文件](https://spark.apache.org/docs/latest/)）。目前需要 Java 17 / 21 / 25，本篇選擇 17 版。
   ![java需求](./java-require.png)

3. 在終端機安裝 Java 17：
    ~~~bash
    yum search java
    sudo yum install java-17-openjdk-headless.x86_64
    readlink -f $(which java)   # 回傳 /usr/lib/jvm/java-17-openjdk-17.0.20.0.8-1.2.el9.x86_64/bin/java

    export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-17.0.20.0.8-1.2.el9.x86_64
    export PATH=$JAVA_HOME/bin:$PATH

    vi ~/.bashrc   # 移到最底部加上下列內容，:wq 保存
      export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-17.0.20.0.8-1.2.el9.x86_64
      export PATH=$JAVA_HOME/bin:$PATH
    source ~/.bashrc   # 讀取生效
    ~~~

4. 設定 `SPARK_HOME` 路徑（非必要，但很方便）。

    {{< admonition tip >}}
    設好 `SPARK_HOME` 之後，之後不管在哪個目錄下都能直接打 `spark-shell` 啟動，不用每次都 `cd` 進 Spark 資料夾用 `./` 執行。長期使用下來，這一步能省掉不少麻煩。
    {{< /admonition >}}

    ~~~bash
    vi ~/.bashrc   # 移到最底部加上下列內容，:wq 保存
      export SPARK_HOME=/home/rick/spark/spark-4.2.0-bin-hadoop3
      export PATH=$SPARK_HOME/bin:$PATH
    source ~/.bashrc   # 讀取生效
    ~~~

5. 測試環境變數是否生效：
   ![Echo Path](./path.png)

## 啟動成功與後續檢查

### 啟用服務

執行以下指令，若得到類似下圖的回傳，就代表安裝成功、環境可以正常運作：

~~~bash
spark-shell
~~~

![Sucess](./sucess.png)

### RDD 測試：1 加到 100

~~~scala
sc.parallelize(1 to 100).sum()
~~~

![1to100](./1to100.png)

### 網頁 UI 查看

這一步需要開放防火牆，讓外部系統能連進來，Spark UI 預設走 **4040 port**。

{{< admonition warning >}}
`--permanent` 參數會讓規則在防火牆重啟後依然生效，等於是永久開放這個 port。如果只是測試環境、用完就關的機器，建議先不加 `--permanent`，或測試結束後記得把規則移除，避免對外長期曝露不必要的服務。
{{< /admonition >}}

~~~bash
sudo firewall-cmd --add-port=4040/tcp --permanent   # 永久參數需視情況使用
sudo firewall-cmd --reload
~~~

![Result](./spark-ui.png)

## 結語

對熟悉用 Python 做資料處理的朋友來說，應該都體會過 Pandas 在大規模資料處理上的侷限：沒有原生分散式能力可以擴充效能、資料量一大處理速度就明顯吃緊。而這些痛點，恰好是 Spark 這套工具的強項。值得一提的是，Spark 對資料處理的方式也支援類 SQL 的語法，上手過程會比想像中親切一些。

以筆者的經驗來說，這是大型 ETL 工具當中，很值得優先投資時間學習的一項技能。

---

> 作者: Rick  
> URL: https://as183789043.github.io/zh-tw/theme-document-spark-install/  

