把 Spark 跑起來:從本機到叢集與 managed 平台
· tech
#spark#data-engineering#deployment
前三篇都在講 Spark 怎麼寫、怎麼跑得快(是什麼、DataFrame 實戰、shuffle 調校)。但同一段程式碼,在你筆電上跑、跟在一個幾十台機器的叢集上跑,中間到底發生什麼事?這篇講 runtime 與部署 —— 從本機單機,一路到 spark-submit、cluster 模式,再到你多半真正會用的 managed 平台。
先搞懂執行架構:Driver、Executor、Cluster Manager
不管跑在哪,一個 Spark 應用永遠是這三個角色:
- Driver:跑你的
main程式、把轉換編成 DAG、切 stage 與 task,然後排程這些 task。它是大腦,但不做粗活。 - Executor:真正幹活的 worker 行程,執行 task、把 cache 的資料存在自己的記憶體裡。一個應用會有很多個 executor 平行跑。
- Cluster Manager:資源的房東 —— Driver 跟它要 CPU 跟記憶體,它去機器上把 executor 開起來。
換部署環境,換的只是 Cluster Manager 跟 Driver 擺哪裡 —— 你的轉換程式碼幾乎不用動。 這是底下所有變化的主軸。
本機:一台機器就能跑
最簡單的起點:pip install pyspark,master 設成 local[*]。這時根本沒有真叢集 —— Driver 跟 Executor 全擠在同一個 JVM,用本機的 N 條執行緒模擬平行。
from pyspark.sql import SparkSession
spark = (SparkSession.builder
.master("local[*]") # * = 用滿所有 CPU 核心
.appName("dev")
.getOrCreate())
它適合開發、測試、跑小資料。別小看它 —— 幾 GB 以內的資料、寫邏輯、除錯,本機模式完全夠用,而且省掉一整套叢集的麻煩。會用到叢集,是因為資料大到一台裝不下、算不完,不是因為「要練 Spark」。
提交到叢集:spark-submit
當資料真的要上叢集,提交的統一入口是 spark-submit:你把程式寫成一個 .py,連同資源需求一起丟出去。
spark-submit \
--master yarn \
--deploy-mode cluster \
--num-executors 10 \
--executor-cores 4 \
--executor-memory 8g \
jobs/daily_etl.py
幾個最常用的旗標:--master(交給哪個 Cluster Manager)、--deploy-mode(Driver 擺哪,見下節)、以及 --num-executors / --executor-cores / --executor-memory 這組決定你跟叢集要多少資源。這幾個數字直接決定平行度與成本,是調效能之外最該搞懂的旋鈕。
client vs cluster:Driver 到底跑在哪
--deploy-mode 是實務最常搞混、也最容易踩坑的一個設定。差別只有一句:Driver 跑在你提交的機器上,還是跑進叢集裡。
client 模式 | cluster 模式 | |
|---|---|---|
| Driver 位置 | 你提交的那台(筆電 / edge node) | 叢集內某個節點 |
| 日誌 | 直接噴回你的終端機 | 要去叢集 / 平台撈 |
| 終端機關掉 | 作業跟著死 | 不受影響,繼續跑 |
| 適合 | 互動式、開發、spark-shell | 正式排程的生產作業 |
新手最常見的災難,就是在本機 client 模式下跑得好好的,搬到生產用排程器觸發時,要嘛 Driver 跟著 session 一起斷、要嘛找不到日誌。生產作業幾乎都該用 cluster 模式 —— 讓 Driver 活在叢集裡,不依賴你那台會關機的機器。生產的觸發通常交給 Airflow 之類的排程器,而它要的正是「提交完就不必掛著」的 cluster 模式。
Cluster Manager 有哪幾種
--master 後面接的就是它。常見三種:
| Cluster Manager | 場景 |
|---|---|
| Standalone | Spark 自帶的簡易管理器,小叢集 / 自架最快上手 |
| YARN | 跟 Hadoop 生態綁定,傳統企業大數據平台主流 |
| Kubernetes | 雲原生時代的主流,Spark 以 pod 形式跑,彈性伸縮好做 |
(早年還有 Mesos,現已式微。)選哪個多半不是你決定的 —— 取決於公司既有的基礎建設。
Managed 平台:你多半不會自己架叢集
上面這些聽起來很硬,但坦白說:多數團隊根本不該自己從零架 Spark 叢集。雲上的 managed 平台幫你把叢集開關、自動伸縮、版本維護全包了,你只管把作業或 notebook 丟上去。
| 平台 | 一句話 |
|---|---|
| Databricks | Spark 原班人馬做的託管平台,notebook + 自動叢集 + lakehouse 一條龍 |
| AWS EMR | AWS 上的託管 Hadoop/Spark 叢集,跟 S3、IAM 整合 |
| AWS Glue | Serverless Spark,連叢集都不用管,適合純 ETL |
| GCP Dataproc | GCP 上的託管 Spark/Hadoop,啟動快、按秒計費 |
它們之間的取捨,本質是「你想管多少」:從 EMR(還看得到叢集)到 Glue(連叢集都被抽象掉)。但不變的是 —— 你前三篇學的那套 DataFrame 與 shuffle 知識,在每個平台上都照用。
反思
Spark 最漂亮的抽象,是「程式碼跟跑在哪解耦」
寫完這篇我更確定一件事:Spark 真正值錢的設計,是同一段轉換邏輯,從本機 local[*] 到十台機器的 YARN 叢集,幾乎一個字都不用改 —— 變的只是 --master 跟 --deploy-mode。這讓我可以在筆電上用小資料把邏輯寫對、測完,再原封不動丟上叢集放大。能享受這個好處的前提,是別在程式裡寫死任何跟環境綁定的東西(路徑、平行度、資源),把那些通通留給提交時的參數。
deploy-mode 是我最常提醒人的坑
「本機跑得動、上生產就炸」十次有八次跟 client/cluster 脫不了關係 —— Driver 擺錯地方,作業跟著終端機一起死,或日誌憑空消失。我的原則很簡單:互動除錯用 client,排程上線一律 cluster。這跟 Airflow 那篇講的冪等與可重跑是同一套思路 —— 生產作業不能依賴「某個人的某台機器剛好開著」。
別為了用 Spark 而架叢集
跟我看 Airflow、看任何基礎建設的態度一模一樣:先確認痛點,再上重武器。 資料還在幾 GB,本機 PySpark 甚至 dbt + 倉儲就解決了,硬架一個叢集只是給自己找維運。真的撞到「單機裝不下、算不完」這道牆,也優先選 managed 平台 —— 把架叢集、調 YARN、修 OOM 的力氣,省下來花在把資料邏輯做對。自架叢集是手段,不是成就。