不依賴Hadoop搭建Spark環境
- 0 概述
- 1 單機安裝Spark
- 1.1 下載Spark預編譯包
- 1.2 解壓和設置
- 1.3 配置環境變量
- 1.4 驗證安裝
- 2 Spark運行模式
- 2.1 Local模式(本地模式)
- 2.1.1 Spark Shell
- 2.1.1.1 Python版的Shell
- 2.1.1.2 Scala版的Shell
- 2.1.2 提交獨立的Spark應用
- 2.2 Local Cluster模式(本地集群模擬模式)
- 2.3 Standalone模式(獨立集群模式)
- 2.3.1 修改主機名
- 2.3.2 配置免密登陸
- 2.3.3 配置master機器
- 2.3.4 配置worker節點
- 2.3.5 啟動集群
- 3 總結
大家好,我是歐陽方超,公眾號同名。
0 概述
Spark環境不依賴Hadoop就可以搭建起來,這對新手小白來說無疑提供了極大的便利。本篇就介紹一下如何在不安裝Hadoop的情況下搭建Spark環境。本文使用的Java、Python版本分別是1.8.0_201、3.11.13。
1 單機安裝Spark
1.1 下載Spark預編譯包
訪問Spark官網下載頁面:https://spark.apache.org/downloads.html
選擇以下選項:
Spark版本:建議選擇最新的穩定版
Package type:選擇 "Pre-built for Apache Hadoop 3.3 and later"2
選擇項 | 推薦值 | 說明 |
---|---|---|
Spar版本 | 最新的穩定版 | 新版本通常性能更好且修復了已知問題 |
Package類型 | Pre-built for Apache Hadoop 3.3 and later | 這種包內包含了常用的Hadoop依賴,無需單獨安裝Hadoop即可運行 |
下載格式 | .tgz壓縮包 | 適用于Linux和Mac系統 |
下圖為我在下載時所做的選擇。
1.2 解壓和設置
解壓下載的Spark壓縮包
[root@192 softwares]# tar -zxvf spark-3.5.6-bin-hadoop3
1.3 配置環境變量
將Spark的可執行文件路徑添加到PATH中,這樣就可以在終端中運行Spark相關命令了。編輯/etc/profile文件,在末尾追加如下內容:
export SPARK_HOME=/softwares/spark-3.5.6-bin-hadoop3
export PATH=$SPARK_HOME/bin:$SPARK_HOME/sbin:$PATH
保存后,運行以下命令使之生效:
source /etc/profile
1.4 驗證安裝
現在可以通過Spark的內置示例驗證安裝是否成功,
run-example SparkPi 10
以上命令是在執行 Spark 自帶的示例程序 SparkPi,該程序的作用是用分布式計算的方式近似計算圓周率 π 的值。其中參數 10 表示將任務劃分成 10 個分區(或切片),Spark 會將計算 π 的任務分成 10 個子任務并行執行。
命令在運行時會輸出包含日志在內的很多內容:
[root@192 softwares]# run-example SparkPi 10
25/08/31 03:14:06 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
25/08/31 03:14:06 INFO SparkContext: Running Spark version 3.5.6
25/08/31 03:14:06 INFO SparkContext: OS info Linux, 3.10.0-1160.el7.x86_64, amd64
25/08/31 03:14:06 INFO SparkContext: Java version 1.8.0_201
25/08/31 03:14:06 INFO ResourceUtils: ==============================================================
25/08/31 03:14:06 INFO ResourceUtils: No custom resources configured for spark.driver.
其中有一個如下的關鍵內容,就是所計算的π的結果,看到這個結果說明Spark已經安裝成功。
Pi is roughly 3.142363142363142
2 Spark運行模式
在不安裝Hadoop的情況下,Spark支持以下幾種運行模式,Local模式(本地模式)、Local Cluster模式(本地集群模擬模式)、Standalone模式(獨立集群模式)、Kubernetes模式、Mesos模式。注意,Spark本身不是一個像MySQL或Nginx那樣一直運行的“服務”,但它運行時會啟動進程并占用端口。
2.1 Local模式(本地模式)
在這種模式下,Spark運行在單個JVM進行中,使用多線程模擬分布式計算。不需要任何集群管理器,適合測試和調試,支持多線程并行。有兩種方式可以以Local模式使用Spark,一種是Spark Shell,另一種是提交獨立的Spark應用。其中Spark Shell又分為Python版的Shell和Scala版的Shell,分別使用pyspark和spark-shell命令進入相應的shell。
2.1.1 Spark Shell
2.1.1.1 Python版的Shell
由于已經為Spark配置過環境變量,所以直接在終端任意位置輸入pyspark即可進入Python版的shell:
[root@192 softwares]# pyspark
Python 3.11.13 (main, Aug 31 2025, 00:02:26) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
25/08/31 03:35:58 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Welcome to____ __/ __/__ ___ _____/ /___\ \/ _ \/ _ `/ __/ '_//__ / .__/\_,_/_/ /_/\_\ version 3.5.6/_/Using Python version 3.11.13 (main, Aug 31 2025 00:02:26)
Spark context Web UI available at http://192.168.152.136:4040
Spark context available as 'sc' (master = local[*], app id = local-1756636559084).
SparkSession available as 'spark'.
>>>
在Python版的Shell中可以執行一下基本的操作,如下面的創建RDD并查看其內容的操作:
>>> # 從集合創建RDD
>>> data = [1, 2, 3, 4, 5]
>>> rdd = sc.parallelize(data)
>>> # 查看RDD內容
>>> rdd.collect()
[1, 2, 3, 4, 5]
>>>
在執行pyspark時,是可以加參數的,比如寫成下面的形式:
pyspark --master local[4] --driver-memory 2g
其中
–master local 表示使用本地模式,利用4個線程運行;
–driver-memory 2g 指定Driver程序使用2GB內存。
2.1.1.2 Scala版的Shell
在終端輸入spark-shell進入Scala版的Shell:
[root@192 spark-3.5.6-bin-hadoop3]# spark-shell
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
25/08/31 03:45:57 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
25/08/31 03:45:59 WARN Utils: Service 'SparkUI' could not bind on port 4040. Attempting port 4041.
Spark context Web UI available at http://192.168.152.136:4041
Spark context available as 'sc' (master = local[*], app id = local-1756637159380).
Spark session available as 'spark'.
Welcome to____ __/ __/__ ___ _____/ /___\ \/ _ \/ _ `/ __/ '_//___/ .__/\_,_/_/ /_/\_\ version 3.5.6/_/Using Scala version 2.12.18 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_201)
Type in expressions to have them evaluated.
Type :help for more information.scala>
同樣也可以進行一些基本操作:
scala> val data = Array(1, 2, 3, 4, 5)
data: Array[Int] = Array(1, 2, 3, 4, 5)scala> val distData = sc.parallelize(data) // sc是SparkContext內置對象
distData: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at parallelize at <console>:24
scala> // 對數據做map變換,乘以2
scala> val doubled = distData.map(x => x * 2)
doubled: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[1] at map at <console>:23
scala>
scala> // 收集結果并打印
scala> doubled.collect().foreach(println)
2
4
6
8
10
scala> // 過濾出大于5的元素
scala> val filtered = doubled.filter(_> 5)
filtered: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[2] at filter at <console>:23
scala> filtered.collect().foreach(println)
6
8
10
scala> val sum = filtered.reduce(_ + _)
sum: Int = 24scala> print(sum)
24
在執行spark-shell命令時,也可以加參數,用法同執行pyspark時所加的參數。
進入兩種版本的Spark Shell后,可以通過訪問Spark Web UI的方式來驗證Spark是否處于運行狀態,可以在瀏覽器輸入ip:4040來訪問頁面:
2.1.2 提交獨立的Spark應用
提交獨立的Spark應用也可以觸發Spark的運行,所謂提交獨立的Spark應用,可以這樣理解,就是把自己的完整程序(Python、Scala、Java)交給Spark去執行,這里Spark充當分布式計算的統一執行平臺,負責調度和管理計算資源,執行你的應用邏輯。
from pyspark.sql import SparkSession# 創建spark會話
spark = SparkSession.builder.appName("WordCount").getOrCreate()
# 得到SparkContext對象
sc = spark.sparkContext# 讀取文本文件得到分布式數據集RDD
lines = sc.textFile("/softwares/words.txt")
# 進行詞頻統計,flatMap將每行拆分成單詞,展平成多個單詞組成的RDD。map將每個單詞映射成鍵值對 (word, 1)。reduceByKey對相同單詞的值進行累加,實現計數。
word_counts = lines.flatMap(lambda line: line.split()).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a + b)
# 將結果保存到指定目錄
word_counts.saveAsTextFile("/softwares/outwords")
# 關閉Spark會話
spark.stop()
執行spark-submit wordcount.py 命令向Spark提交任務,由Spark來執行分布式計算,輸出日志非常長,這里只貼出一部分(結尾部分和開頭部分的日志):
[root@192 softwares]# spark-submit wordcount.py
開頭部分的日志
25/08/31 07:27:46 INFO SparkContext: Running Spark version 3.5.6
25/08/31 07:27:46 INFO SparkContext: OS info Linux, 3.10.0-1160.el7.x86_64, amd64
25/08/31 07:27:46 INFO SparkContext: Java version 1.8.0_201
25/08/31 07:27:46 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
25/08/31 07:27:46 INFO ResourceUtils: ==============================================================
25/08/31 07:27:46 INFO ResourceUtils: No custom resources configured for spark.driver.
25/08/31 07:27:46 INFO ResourceUtils: ==============================================================
25/08/31 07:27:46 INFO SparkContext: Submitted application: WordCount結尾部分的日志
25/08/31 07:27:56 INFO SparkUI: Stopped Spark web UI at http://192.168.152.137:4040
25/08/31 07:27:56 INFO MapOutputTrackerMasterEndpoint: MapOutputTrackerMasterEndpoint stopped!
25/08/31 07:27:56 INFO MemoryStore: MemoryStore cleared
25/08/31 07:27:56 INFO BlockManager: BlockManager stopped
25/08/31 07:27:56 INFO BlockManagerMaster: BlockManagerMaster stopped
25/08/31 07:27:56 INFO OutputCommitCoordinator$OutputCommitCoordinatorEndpoint: OutputCommitCoordinator stopped!
25/08/31 07:27:56 INFO SparkContext: Successfully stopped SparkContext
25/08/31 07:27:56 INFO ShutdownHookManager: Shutdown hook called
25/08/31 07:27:56 INFO ShutdownHookManager: Deleting directory /tmp/spark-00e7ab02-1f2c-4861-9de6-16ed3ced686b
25/08/31 07:27:56 INFO ShutdownHookManager: Deleting directory /tmp/spark-a816c18c-202f-4b91-aa79-d32821644f77/pyspark-23d851b4-546f-4c1b-8816-bb30775d9966
25/08/31 07:27:56 INFO ShutdownHookManager: Deleting directory /tmp/spark-a816c18c-202f-4b91-aa79-d32821644f77
執行完畢后,會在指定的輸出目錄中生成下面兩個文件:
[root@192 softwares]# cd outwords/
[root@192 outwords]# ll
總用量 4
-rw-r--r--. 1 root root 50 8月 31 07:27 part-00000
-rw-r--r--. 1 root root 0 8月 31 07:27 _SUCCESS
part-00000這個文件里存放的是數據處理結果,不妨看下結果:
[root@192 outwords]# cat part-00000
('test', 1)
('hello', 1)
('ketty', 1)
('word', 1)
2.2 Local Cluster模式(本地集群模擬模式)
這種模式是在單臺機器上模擬一個Spark集群環境,這種模式尤其適合沒有Hadoop環境時的開發和測試工作。啟動命令pyspark需要加參數,語法如下(以pyspark為例):
pyspark --conf "spark.master=local-cluster[numNodes, coresPerNode, memoryPerNode]"
spark.master是Spark應用的主節點(master)的配置參數,決定了Spark應用運行的模式。local-cluster[numNodes, coresPerNode, memoryPerNode]表示本地模擬一個Spark集群,nmNodes是模擬集群中節點(word)的數量,coresPerNode是每個節點的CPU核心數,memoryPerNode是每個節點分配的內存數。
執行下面的命令進入Local Cluster模式,使用兩個節點,每個節點分配一個CPU核心和1G內存:
[root@192 softwares]# pyspark --conf "spark.master=local-cluster[2,1,1024]"
執行下面的代碼:
text = ["hello world", "hello spark", "spark is fast"]
rdd = sc.parallelize(text)word_counts = rdd.flatMap(lambda line: line.split(" ")) \.map(lambda word: (word, 1)) \.reduceByKey(lambda a, b: a + b)# Check the execution plan
print(word_counts.toDebugString().decode('utf-8'))
word_counts.collect()
執行結果:
>>> text = ["hello world", "hello spark", "spark is fast"]
>>> rdd = sc.parallelize(text)
>>>
>>> word_counts = rdd.flatMap(lambda line: line.split(" ")) \
... .map(lambda word: (word, 1)) \
... .reduceByKey(lambda a, b: a + b)
>>>
>>> # Check the execution plan
>>> print(word_counts.toDebugString().decode('utf-8'))
(2) PythonRDD[11] at RDD at PythonRDD.scala:53 []| MapPartitionsRDD[10] at mapPartitions at PythonRDD.scala:160 []| ShuffledRDD[9] at partitionBy at NativeMethodAccessorImpl.java:0 []+-(2) PairwiseRDD[8] at reduceByKey at <stdin>:3 []| PythonRDD[7] at reduceByKey at <stdin>:3 []| ParallelCollectionRDD[6] at readRDDFromFile at PythonRDD.scala:289 []
>>> word_counts.collect()
[('hello', 2), ('fast', 1), ('world', 1), ('spark', 2), ('is', 1)]
>>>
從命令行的執行結果,似乎也看不出來Local Cluster模式與Local模式有什么區別,但是從Web UI上還是能看出些區別的,比如下圖中Alive Workers顯示為2。
還有一些其他區別,歸納成下表形式:
特性 | Local 模式 | Local Cluster 模式 |
---|---|---|
進程數 | 1個JVM進程 | 多個JVM進程(模擬分布式) |
資源隔離 | 無隔離 | 模擬資源隔離 |
適用場景 | 簡單測試 | 模擬分布式環境測試 |
Web UI端口 | 4040端口 | 4041、4042…等端口 |
啟動命令 | local[N] | local-cluster[N,M,mem] |
2.3 Standalone模式(獨立集群模式)
這種模式是由多臺機器組成的Spark集群,通過Spark自帶的集群管理器實現任務的調度與執行,每臺服務器部署Spark守護進程,包括Master和多個Worker,Master負責集群資源管理和任務調度,Worker運行Executor執行任務,啟動前需配置集群環境,支持多用戶并發使用。
2.3.1 修改主機名
這里規劃三臺機器,三臺機器的名稱分別命為centos7-master、centos7-node1、centos7-node2,一臺機器作為Master節點,負責集群管理和調度,其余兩臺作為Worker節點,負責執行計算任務。
設置主機名之前最好先查看一下主機名,可以使用下面的命令:
hostname
如果確定要修改主機名的話,可以使用下面的命令(當然還有其他方式):
hostnamectl set-hostname 新主機名
該命令會更新/etc/hostname文件,并立即生效。
然后在每臺機器的/etc/hosts文件中都寫入三臺機器IP與主機名的映射關系,便于機器之間通過主機名進行訪問:
#master
192.168.152.152 centos7-master
#node1
192.168.152.151 centos7-node1
#node2
192.168.152.150 centos7-node2
2.3.2 配置免密登陸
Spark的Master節點需要遠程管理和啟動各個Worker節點的進程,免密登錄使Master節點無障礙地遠程執行命令,無需每次都輸入密碼,保證集群自動化管理。
之前三臺機器設置的主機名為centos7-master、centos7-node1、centos7-node2,先在centos7機器上生成SSH密鑰對,一路回車使用默認路徑(~/.ssh/id_rsa),不設置密碼:
ssh-keygen -t rsa
然后,使用ssh-copy-id命令將公鑰復制到另外兩臺機器上:
ssh-copy-id centos7-node1
ssh-copy-id centos7-node2
若沒有ssh-copy-id工具,也可手動復制~/.ssh/id_rsa.pub
內容添加到目標機器~/.ssh/authorized_keys文件。
然后在另外兩臺機器上也執行同樣的操作,目的就是保證每個機器上都有另外兩臺機器產生的公鑰。
接著可以使用ssh命令測試機器間登錄是否已經免密了。
配置好免密登錄后,Master節點就能無密碼遠程管理Worker節點,啟動和停止Spark進程時無需人工干預。
2.3.3 配置master機器
在master節點要創建兩個配置文件,workers和spark-en.sh。
進入Spark解壓目錄的config文件夾,基于workers.template文件復制workers文件(使用cp命令),接著編輯workers文件,寫入Worker節點的主機名或IP地址:
centos7-node1
centos7-node2
同樣在config文件夾中,復制出一份spark-env.sh文件,master節點的spark-env.sh文件主要配置以下內容:
export JAVA_HOME=/softwares/jdk1.8.0_201export SPARK_MASTER_HOST=centos7-masterexport SPARK_MASER_PORT=7077export SPARK_MASTER_WEBUI_PORT=8080
JAVA_HOME:Java路徑
SPARK_MASTER_HOST:Master節點綁定的主機名(或IP),這是必須配置的
SPARK_MASTER_PORT:Master節點監聽的端口號,默認7077端口,Worker和Driver通過這個端口連接到Master,如果該端口沒被占用,可以不設置
SPARK_MASTER_WEBUI_PORT:訪問Spark Standalone集群的界面(Master Web UI)端口(默認為8080)
2.3.4 配置worker節點
worker節點中不需要配置workers文件,只需配置spark-env.sh文件,需要配置的內容跟master節點上配置的稍微有所不同,具體來說只需配置JAVA_HOME和一些資源參數即可:
export JAVA_HOME=/softwares/jdk1.8.0_201
export SPARK_WORKER_CORES=2
export SPARK_WORKER_MEMORY=4g
SPARK_WORKER_CORES=2表示該Worker節點上分配給Spark任務執行的CPU核心數為2個,SPARK_WORKER_MEMORY=4g表示該Worker節點分配給Spark任務執行的最大內存為4GB。
2.3.5 啟動集群
在Master節點運行:
./sbin/start-master.sh
./sbin/start-slaves.sh
或直接運行一鍵啟動:
./sbin/start-all.sh
jps命令查看進程
可以通過在每個節點上查看進程的方式(執行jps命令)驗證集群是否啟動成功:
[root@centos7-master ~]# jps
13779 Jps
13695 Master
[root@centos7-node1 ~]# jps
12485 Worker
12573 Jps
[root@centos7-node2 ~]# jps
12247 Worker
12365 Jps
訪問Web UI
Spark集群啟動后,可以通過主機IP:默認端口名方式方式集群的界面
3 總結
如果暫時沒有Hadoop環境,又想使用Spark,Spark提供了Local模式、Local Cluster模式、Standalone三種模式,這三種模式允許開發者在不使用Hadoop的情況也能搭建Spark環境。
我是歐陽方超,把事情做好了自然就有興趣了,如果你喜歡我的文章,歡迎點贊、轉發、評論加關注。我們下次見。