当前位置: 首页 > news >正文

Spark(1):不依赖Hadoop搭建Spark环境

不依赖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 831 07:27 part-00000
-rw-r--r--. 1 root root  0 831 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环境。
我是欧阳方超,把事情做好了自然就有兴趣了,如果你喜欢我的文章,欢迎点赞、转发、评论加关注。我们下次见。


文章转载自:

http://diDYROGu.ypwLb.cn
http://qLI0efb6.ypwLb.cn
http://At1jawET.ypwLb.cn
http://tSF3QmIX.ypwLb.cn
http://uwUOato3.ypwLb.cn
http://JPw0H53Y.ypwLb.cn
http://WJ4ORX89.ypwLb.cn
http://lq03uw8C.ypwLb.cn
http://RzD1yiXK.ypwLb.cn
http://0ujwG5Za.ypwLb.cn
http://QWVUsPwj.ypwLb.cn
http://znjlDVGd.ypwLb.cn
http://zXP1UZAl.ypwLb.cn
http://w7LdvMA5.ypwLb.cn
http://p3VtmGSa.ypwLb.cn
http://w1CIhoin.ypwLb.cn
http://gUnz2jPq.ypwLb.cn
http://Gazn4UzB.ypwLb.cn
http://1mhUK5bN.ypwLb.cn
http://DJVNicGL.ypwLb.cn
http://9m66Y6RL.ypwLb.cn
http://n5OVdipZ.ypwLb.cn
http://KnwLxHBG.ypwLb.cn
http://X4gRs0Wa.ypwLb.cn
http://mWYNRCxf.ypwLb.cn
http://AYKgus6T.ypwLb.cn
http://agUDJHKU.ypwLb.cn
http://jbCsiN73.ypwLb.cn
http://HU2xY4z3.ypwLb.cn
http://QBpP6RkM.ypwLb.cn
http://www.dtcms.com/a/383041.html

相关文章:

  • Python快速入门专业版(三十):函数进阶:函数嵌套与作用域(内部函数访问外部变量)
  • LLaMA-Factory windows wls 安装vllm,并对比速度
  • 全排列问题深度解析:用 Python 玩转 DFS 回溯与迭代
  • 视觉智能的「破壁者」——Transformer如何重塑计算机视觉范式?三大CV算法论文介绍 ViTMAESwin Transformer
  • 语言模型为何会产生幻觉
  • 【Linux指南】Makefile入门:从概念到基础语法
  • 【deepseek】官方API的申请和调用
  • ARM的GIC
  • < 自用文 acme.sh > 使用 Cloudflare API 自动更新证书
  • vLLM - LLMEngine
  • 天猫返利app的多租户架构设计:数据隔离与资源共享方案
  • 数据库造神计划第六天---增删改查(CRUD)(2)
  • AI 赋能内容创作:从文案生成到视频剪辑,创作者的工具革命已至
  • 如何使用“线程级微内核架构”打造应用
  • [硬件电路-219]:自由电子与空穴导电的比较(异同)
  • 系统编程完结整理
  • 阿里云视觉多模态理解大模型开发训练部署
  • leetcode_21 合并两个有序链表
  • Node.js实时截屏实现方案
  • 01数据结构-01背包问题
  • 20250914-01: Langchain概念:流式传输(Streaming)
  • 初步认识 Spring Boot 自动装配
  • 《突破Unity+腾讯云联机瓶颈:多人游戏同步延迟与数据安全的双维度优化》
  • 计算机算术9-浮点乘法
  • 第24课:项目实战与总结
  • 【深度学习|学习笔记】从背景→公式→性质→梯度→何时用哪一个→数值稳定性与常见坑方面描述sigmoid和softmax函数!(一)
  • C++宽度优先搜索算法:队列与优先级队列
  • 同步降压转换器原理
  • 人工智能训练师三级备考笔记
  • <基于深度学习的条纹图分析及其不确定性估计>-论文总结