Spark 3.5.0 伪分布式 Standalone 模式搭建:Ubuntu 22.04 单机 2 节点配置与测试
1. 环境准备与核心概念
在单台物理机或虚拟机上模拟分布式集群环境,是开发者验证Spark应用逻辑的高效方式。Standalone模式作为Spark内置的轻量级集群管理器,无需依赖Hadoop YARN或Mesos,特别适合快速搭建测试环境。以下是关键组件说明:
- Master节点:负责资源调度和集群管理,默认监听7077端口(RPC通信)和8080端口(Web UI)
- Worker节点:执行具体计算任务,向Master汇报资源情况
- 伪分布式模式:通过单机多进程模拟多节点环境,降低硬件需求
系统要求:
- Ubuntu 22.04 LTS(内核版本5.15+)
- Java 8/11(推荐OpenJDK 11)
- 至少4GB内存(建议8GB)
- 20GB可用磁盘空间
# 验证Java环境 java -version # 应输出类似内容 openjdk version "11.0.22" 2024-01-16 OpenJDK Runtime Environment (build 11.0.22+7-post-Ubuntu-0ubuntu222.04.1)2. 安装与基础配置
2.1 获取Spark安装包
从Apache镜像站下载预编译版本(选择与Hadoop无关的版本):
wget https://archive.apache.org/dist/spark/spark-3.5.0/spark-3.5.0-bin-without-hadoop.tgz sha512sum spark-3.5.0-bin-without-hadoop.tgz | grep -i $(curl -s https://archive.apache.org/dist/spark/spark-3.5.0/spark-3.5.0-bin-without-hadoop.tgz.sha512)解压并建立软链接:
tar -xzf spark-3.5.0-bin-without-hadoop.tgz -C /opt ln -s /opt/spark-3.5.0-bin-without-hadoop /opt/spark2.2 环境变量配置
编辑/etc/profile.d/spark.sh:
export SPARK_HOME=/opt/spark export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin export PYSPARK_PYTHON=python3立即生效配置:
source /etc/profile3. 伪分布式集群配置
3.1 核心配置文件修改
进入配置目录并复制模板文件:
cd $SPARK_HOME/conf cp spark-env.sh.template spark-env.sh cp workers.template workersspark-env.sh关键配置:
# 设置Master主机(本机IP或主机名) export SPARK_MASTER_HOST=$(hostname -I | awk '{print $1}') # 资源配置(根据实际硬件调整) export SPARK_WORKER_CORES=2 export SPARK_WORKER_MEMORY=2g export SPARK_DAEMON_MEMORY=1g # Java环境 export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 # 日志配置(可选) export SPARK_LOG_DIR=/var/log/spark export SPARK_WORKER_DIR=/tmp/spark/workerworkers文件配置:
localhost注意:伪分布式模式下,workers文件只需包含localhost即可,Spark会自动启动多个Worker进程
3.2 目录权限设置
创建日志和工作目录:
sudo mkdir -p /var/log/spark /tmp/spark/worker sudo chown -R $USER:$USER /var/log/spark /tmp/spark4. 集群启动与验证
4.1 启动集群服务
使用内置脚本启动服务:
start-all.sh验证进程是否正常:
jps # 应包含以下进程 # Master # Worker4.2 Web UI访问
通过浏览器访问Master的Web界面(默认8080端口):
http://<your-server-ip>:8080正常界面应显示:
- 1个Alive的Worker
- Worker的CPU和内存资源信息
- 当前运行的Applications(应为空)
4.3 命令行验证
通过spark-shell连接集群:
spark-shell --master spark://$(hostname -I | awk '{print $1}'):7077在Scala REPL中执行测试:
val data = 1 to 10000 val distData = sc.parallelize(data) distData.map(_ * 2).reduce(_ + _)5. 实战案例:WordCount作业提交
5.1 准备测试数据
创建示例文件:
echo "hello spark hello world" > /tmp/test.txt5.2 提交Python版WordCount
创建wordcount.py:
from pyspark.sql import SparkSession spark = SparkSession.builder.appName("WordCount").getOrCreate() lines = spark.read.text("/tmp/test.txt").rdd.map(lambda r: r[0]) counts = lines.flatMap(lambda x: x.split(' ')) \ .map(lambda word: (word, 1)) \ .reduceByKey(lambda a, b: a + b) output = counts.collect() for (word, count) in output: print("%s: %i" % (word, count)) spark.stop()提交作业:
spark-submit \ --master spark://$(hostname -I | awk '{print $1}'):7077 \ wordcount.py5.3 提交Scala版WordCount
创建WordCount.scala:
import org.apache.spark.{SparkConf, SparkContext} object WordCount { def main(args: Array[String]) { val conf = new SparkConf().setAppName("WordCount") val sc = new SparkContext(conf) val textFile = sc.textFile("/tmp/test.txt") val counts = textFile.flatMap(line => line.split(" ")) .map(word => (word, 1)) .reduceByKey(_ + _) counts.saveAsTextFile("/tmp/wordcount_output") sc.stop() } }编译打包后提交:
spark-submit \ --class WordCount \ --master spark://$(hostname -I | awk '{print $1}'):7077 \ target/scala-2.12/wordcount_2.12-1.0.jar6. 性能调优与问题排查
6.1 常见配置优化
| 参数 | 推荐值 | 说明 |
|---|---|---|
| spark.executor.memory | 1g-2g | 每个Executor内存 |
| spark.driver.memory | 1g | Driver进程内存 |
| spark.default.parallelism | Worker核心数×2 | 默认并行度 |
| spark.sql.shuffle.partitions | 200 | SQL操作分区数 |
在spark-defaults.conf中添加:
spark.executor.memory 2g spark.driver.memory 1g spark.default.parallelism 46.2 典型问题解决
问题1:端口冲突
java.net.BindException: Address already in use解决方案:
- 修改
spark-env.sh中的端口号 - 或终止占用端口的进程
问题2:内存不足
java.lang.OutOfMemoryError: Java heap space解决方案:
- 增加
SPARK_WORKER_MEMORY值 - 或减少并行任务数
问题3:Python依赖缺失
ImportError: No module named pandas解决方案:
- 使用
--py-files提交依赖包 - 或在所有节点安装相同Python环境
7. 集群管理与监控
7.1 常用管理命令
| 命令 | 功能 |
|---|---|
stop-all.sh | 停止所有服务 |
start-history-server.sh | 启动历史服务器 |
spark-class org.apache.spark.deploy.Client | 手动提交应用 |
7.2 日志查看技巧
- Master日志:
$SPARK_HOME/logs/spark--master-*.out - Worker日志:
$SPARK_HOME/logs/spark--worker-*.out - 应用日志:Web UI的Executors标签页
实时监控日志:
tail -f /var/log/spark/spark--org.apache.spark.deploy.master.Master-1-*.out8. 扩展配置
8.1 启用历史服务器
- 创建日志目录:
hdfs dfs -mkdir /spark-logs- 配置
spark-defaults.conf:
spark.eventLog.enabled true spark.eventLog.dir hdfs://localhost:9000/spark-logs spark.history.fs.logDirectory hdfs://localhost:9000/spark-logs- 启动服务:
start-history-server.sh8.2 集成Jupyter Notebook
安装并配置:
pip install jupyter pyspark echo "export PYSPARK_DRIVER_PYTHON=jupyter" >> ~/.bashrc echo "export PYSPARK_DRIVER_PYTHON_OPTS='notebook --ip=0.0.0.0'" >> ~/.bashrc启动带集群支持的Notebook:
pyspark --master spark://$(hostname -I | awk '{print $1}'):7077