简介:spark-3.2.0-bin-hadoop3.2.tgz 是 Apache Spark 3.2.0 面向 Hadoop 3.2 环境编译的官方二进制发行包,适合大数据开发工程师、数据科学家及机器学习从业者快速搭建分布式计算环境,免去源码编译环节。压缩包共 1476 个文件,约 287.02MB,以 462 个 py、238 个 jar、203 个 scala、135 个 java 文件为主,涵盖 PySpark 接口、核心依赖库、Scala 与 Java 源码示例,另含 sh、cmd 启动脚本及 parquet、orc、csv 等样例数据,目录结构完整清晰。该版本在性能、SQL 优化、Python API、Kubernetes 原生支持等方面均有增强,并改进内存管理与生态互操作性。已有 1124 人学习下载,解压后可直接在 Hadoop 3.2 集群运行 Spark 作业,便于开展数据分析、流处理与模型训练实践。
1. Spark 3.2.0 搭配 Hadoop 3.2 的安装包,为什么总有人卡在第一步
拿到spark-3.2.0-bin-hadoop3.2.tgz这个包的人,多半不是第一次碰大数据组件。但奇怪的是,每年还是有一批人卡在解压之后——spark-shell敲下去,要么报JAVA_HOME is not set,要么连HADOOP_CONF_DIR都找不到,要么干脆启动到一半抛个NoClassDefFoundError。这个包本身是 Spark 官方为 Hadoop 3.2 预编译的版本,省掉了自己编译的麻烦,但它对 JDK 版本、环境变量、Hadoop 客户端配置的依赖一点没少。我见过太多人把 tgz 解压完就以为装好了,结果连一个spark-submit都跑不起来。这篇笔记就是给那些手里已经拿到这个包、准备在本地或测试集群上把它跑通的人看的,从 JDK 选型一路写到验证跑通,中间踩过的坑一并列出来。
2. 装之前先把环境对齐:JDK、Hadoop、路径一个都不能错
2.1 JDK 版本选择:Spark 3.2.0 只认 8 和 11
Spark 3.2.0 官方编译时用的 Scala 版本是 2.12,运行时对 JDK 的要求是 JDK 8 或 JDK 11。JDK 17 在这个版本上会直接抛IllegalAccessError,因为模块化之后反射相关的包被封装了。我一般会选 JDK 8,原因是 Hadoop 3.2 的很多客户端库在 JDK 8 上最稳,JDK 11 虽然也能跑,但偶尔会遇到javax.xml.bind相关的类找不到,需要额外加--add-modules java.xml.bind参数。
检查当前 JDK 版本:
java -version # 期望输出类似: # openjdk version "1.8.0_362" # OpenJDK Runtime Environment (build 1.8.0_362-b08)如果系统里装了多个 JDK,用update-alternatives切换:
sudo update-alternatives --config java # 交互式选择 JDK 8 对应的编号这里的关键是JAVA_HOME必须指向 JDK 根目录,而不是bin目录。很多人写成了/usr/lib/jvm/java-8-openjdk-amd64/bin,结果 Spark 启动脚本拼路径时找不到lib/tools.jar。
2.2 Hadoop 客户端依赖:不是装了 Hadoop 就行
spark-3.2.0-bin-hadoop3.2.tgz这个包名里的hadoop3.2指的是编译时链接的 Hadoop 版本,不代表你机器上必须装一个完整的 Hadoop 集群。如果你只是本地跑 Spark,不碰 HDFS 和 YARN,那不需要装 Hadoop,Spark 自带的 jar 包已经够用。但如果你要读写 HDFS 或者提交到 YARN,就需要一个 Hadoop 客户端环境。
常见做法是下载一个同版本的 Hadoop 二进制包,解压后只配环境变量,不启动任何服务:
# 假设 Hadoop 解压在 /opt/hadoop-3.2.1 export HADOOP_HOME=/opt/hadoop-3.2.1 export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop export PATH=$PATH:$HADOOP_HOME/binHADOOP_CONF_DIR这个变量特别容易被忽略。Spark 提交任务到 YARN 时,会从这个目录读取core-site.xml、hdfs-site.xml、yarn-site.xml。如果没配,你会看到Could not find or load main class org.apache.hadoop.mapreduce...或者连接0.0.0.0:8032被拒绝。
2.3 环境变量清单:照着这个表配就不会漏
| 变量名 | 是否必须 | 典型值 | 作用 |
|---|---|---|---|
| JAVA_HOME | 必须 | /usr/lib/jvm/java-8-openjdk-amd64 | 指定 JDK 根目录 |
| SPARK_HOME | 必须 | /opt/spark-3.2.0-bin-hadoop3.2 | Spark 解压目录 |
| HADOOP_HOME | 按需 | /opt/hadoop-3.2.1 | Hadoop 客户端根目录 |
| HADOOP_CONF_DIR | 按需 | $HADOOP_HOME/etc/hadoop | Hadoop 配置文件目录 |
| SPARK_CONF_DIR | 可选 | $SPARK_HOME/conf | Spark 配置文件目录,默认已指向 |
| PATH | 必须 | 追加 $SPARK_HOME/bin | 让 spark-shell 等命令可直接调用 |
把这些写进~/.bashrc或/etc/profile.d/spark.sh,然后source一下。我习惯单独建一个/etc/profile.d/spark.sh,这样多用户环境下每个人都能用到,不用各自改自己的 bashrc。
3. 解压与基础配置:从 tgz 到能敲 spark-shell
3.1 解压位置和权限处理
拿到 tgz 之后,别急着在下载目录里解压。我一般放到/opt下面,统一管理:
sudo tar -zxvf spark-3.2.0-bin-hadoop3.2.tgz -C /opt/ sudo chown -R $(whoami):$(whoami) /opt/spark-3.2.0-bin-hadoop3.2第二行是改属主。如果你用 root 解压,普通用户跑spark-shell时会因为写不了work目录而报权限错误。改属主比每次sudo要省事。
解压完之后确认目录结构:
ls /opt/spark-3.2.0-bin-hadoop3.2/ # 应该看到 bin/ conf/ jars/ sbin/ examples/ 等目录bin/里是spark-shell、spark-submit、pyspark这些入口脚本,conf/里默认只有几个.template文件,需要自己复制成正式配置。
3.2 配置 spark-env.sh:内存和端口在这里定
进入conf目录,复制模板:
cd /opt/spark-3.2.0-bin-hadoop3.2/conf cp spark-env.sh.template spark-env.sh编辑spark-env.sh,加上这几行:
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 export SPARK_MASTER_HOST=127.0.0.1 export SPARK_MASTER_PORT=7077 export SPARK_WORKER_MEMORY=2g export SPARK_WORKER_CORES=2 export SPARK_LOCAL_IP=127.0.0.1SPARK_MASTER_HOST和SPARK_LOCAL_IP这两个参数在单机伪分布式场景下必须显式指定。不写的话,Spark 会尝试用主机名去绑定,而很多容器或虚拟机环境里主机名解析有问题,导致启动后 Web UI 打不开或者 Worker 注册不上。SPARK_WORKER_MEMORY控制每个 Worker 能分配的内存,本地测试给 2g 足够,给太大反而会挤占系统内存。
3.3 配置 slaves 文件:单机就写一行
cp slaves.template slaves echo "127.0.0.1" > slaves这个文件只在start-all.sh启动 Standalone 集群时用。如果你只用spark-shell本地模式,这个文件可以不管。但既然装都装了,配一行不费事,后面想试集群模式直接就能用。
3.4 日志级别调整:别让 INFO 刷屏
Spark 默认日志级别是 INFO,spark-shell一启动满屏都是心跳和调度信息。改conf/log4j.properties:
cp log4j.properties.template log4j.properties把这一行:
log4j.rootCategory=INFO, console改成:
log4j.rootCategory=WARN, console这样只有警告和错误才会打印,调试的时候再改回 INFO。我一般会在第一次跑通之后就把这个改掉,不然终端里找自己的输出很费劲。
4. 启动与验证:spark-shell、pyspark、spark-submit 三条路都走一遍
4.1 spark-shell 交互式验证
最直接的验证方式就是敲spark-shell:
spark-shell正常的话会看到 Spark 的 ASCII logo 和版本信息,最后停在scala>提示符。这时候可以跑一段简单的 WordCount:
val data = Seq("hello spark", "hello hadoop", "spark on hadoop") val rdd = sc.parallelize(data) val counts = rdd.flatMap(_.split(" ")).map((_, 1)).reduceByKey(_ + _) counts.collect().foreach(println)预期输出每个单词和它的计数。如果这一步能跑通,说明 Spark 核心运行时没问题。如果卡在scala>之前不动,多半是SPARK_LOCAL_IP没配或者端口被占用,看logs/目录下的日志文件能定位到具体原因。
4.2 pyspark 验证 Python 环境
如果你用 Python,跑pyspark:
pyspark进入之后:
data = ["hello spark", "hello python", "spark with python"] rdd = sc.parallelize(data) counts = rdd.flatMap(lambda line: line.split(" ")).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a + b) for word, count in counts.collect(): print(f"{word}: {count}")Python 环境需要注意的是PYSPARK_PYTHON变量。如果系统里默认python指向 Python 3,而 Spark 脚本里写的是python,一般没问题。但如果你的 Python 装在非标准路径,需要在spark-env.sh里加:
export PYSPARK_PYTHON=/usr/bin/python34.3 spark-submit 提交一个实际任务
交互式跑通之后,用spark-submit提交一个 jar 包或者 Python 脚本,模拟真实提交场景:
spark-submit \ --master local[2] \ --class org.apache.spark.examples.SparkPi \ $SPARK_HOME/examples/jars/spark-examples_2.12-3.2.0.jar \ 10这个命令跑的是 Spark 自带的计算 Pi 的示例。--master local[2]表示本地模式用两个线程,10是计算轮数。输出里会打印Pi is roughly 3.14...。这一步验证的是spark-submit脚本的参数解析和类加载路径没问题。
如果报ClassNotFoundException,检查 jar 包路径是不是写错了,或者SPARK_HOME有没有正确导出。如果报java.lang.OutOfMemoryError,把local[2]改成local[1]或者调大spark.driver.memory。
4.4 Web UI 确认运行状态
Spark 启动后会开一个 Web UI,默认端口 4040。浏览器访问http://127.0.0.1:4040,能看到 Jobs、Stages、Storage、Environment 几个标签页。Environment 页里会列出所有生效的 Spark 配置项和系统属性,这是排查配置是否生效的最快方式。如果 4040 打不开,先确认进程还在不在,再看SPARK_LOCAL_IP是不是绑到了 127.0.0.1 以外的地址。
5. 避坑与排查:五个最容易翻车的地方
5.1 现象:spark-shell 启动报JAVA_HOME is not set
原因:spark-env.sh里没配JAVA_HOME,或者配的路径不对。Spark 的启动脚本会先读spark-env.sh,读不到才去读系统环境变量。如果你只在.bashrc里导出了JAVA_HOME,但spark-env.sh里没有,某些执行方式下会拿不到。
解决:在spark-env.sh里显式写一行export JAVA_HOME=/你的/jdk/路径,路径用readlink -f $(which java)反推,去掉末尾的/bin/java。
5.2 现象:提交到 YARN 时报Could not find or load main class
原因:HADOOP_CONF_DIR没配,或者配的目录里缺少yarn-site.xml。Spark 提交到 YARN 时需要从HADOOP_CONF_DIR读取 ResourceManager 地址和队列配置。
解决:确认HADOOP_CONF_DIR指向的目录里有core-site.xml和yarn-site.xml,并且fs.defaultFS和yarn.resourcemanager.hostname配置正确。可以用hadoop classpath命令检查 Hadoop 客户端是否能正常加载配置。
5.3 现象:Python 脚本报No module named pyspark
原因:PYTHONPATH里没有加入$SPARK_HOME/python和$SPARK_HOME/python/lib/py4j-*.zip。pyspark命令本身会处理这个路径,但如果你直接用python your_script.py而不是spark-submit your_script.py,就需要手动加。
解决:在spark-env.sh里加:
export PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/lib/py4j-0.10.9-src.zip:$PYTHONPATHpy4j 的版本号根据$SPARK_HOME/python/lib/下的实际文件名调整。
5.4 现象:Worker 节点注册不上 Master
原因:SPARK_MASTER_HOST配成了localhost或者主机名,而 Worker 用 IP 去连,解析不到。或者防火墙挡了 7077 端口。
解决:SPARK_MASTER_HOST统一用 IP,SPARK_LOCAL_IP也统一用 IP。检查ss -tlnp | grep 7077确认端口在监听。如果是多机环境,确认 Master 和 Worker 之间网络可达。
5.5 现象:跑任务时频繁 Full GC 或者 OOM
原因:SPARK_WORKER_MEMORY给得太大,超过了物理内存,或者spark.driver.memory默认 1g 不够用。
解决:本地模式下调小 Worker 内存,调大 Driver 内存:
spark-shell --driver-memory 2g --executor-memory 2g或者在spark-defaults.conf里写死:
spark.driver.memory 2g spark.executor.memory 2g spark.executor.cores 26. 装完之后怎么确认真的跑通了:一个可复现的验证清单
装完 Spark 最怕的就是“看起来装好了,一跑就报错”。我一般会按下面这个清单从头走一遍,每一步都有明确的预期输出,任何一步对不上就停下来排查,不往后走。
第一步,环境变量自检。开一个新终端,依次执行:
echo $JAVA_HOME echo $SPARK_HOME which spark-shell三个命令都应该有输出,which spark-shell应该指向$SPARK_HOME/bin/spark-shell。如果which找不到,说明PATH没配好,回到第 2 章检查。
第二步,版本一致性检查。执行:
spark-submit --version输出里会显示 Spark 版本 3.2.0 和 Scala 版本 2.12.x。确认 Scala 版本是 2.12 而不是 2.11,因为spark-3.2.0-bin-hadoop3.2.tgz默认编译的是 Scala 2.12,如果你拿了一个 Scala 2.11 编译的第三方 jar 来提交,会报NoSuchMethodError。
第三步,本地模式跑通 WordCount。用spark-shell跑一遍第 4 章里的 WordCount 代码,确认counts.collect()能返回结果。这一步验证的是 RDD 的基本算子链路。
第四步,提交模式跑通示例 jar。用spark-submit提交SparkPi示例,确认输出Pi is roughly 3.14。这一步验证的是spark-submit的参数解析和类加载。
第五步,Web UI 确认配置生效。访问http://127.0.0.1:4040/environment/,在页面里搜索spark.driver.memory和spark.executor.memory,确认值和你配的一致。这一步验证的是配置文件被正确加载。
第六步,日志目录检查。看一眼$SPARK_HOME/logs/下面有没有.out和.log文件,.out里是标准输出和标准错误,.log里是 log4j 写的日志。如果启动失败但终端没报错,答案多半在这两个文件里。
这六步走完,基本能覆盖 90% 的安装配置问题。剩下的 10% 通常是特定环境下的网络策略或者权限问题,那就得具体环境具体看了。
提示:每次改完
spark-env.sh或spark-defaults.conf,都要重新开一个终端或者source一下,否则当前 shell 里的环境变量还是旧的。我吃过这个亏,改完配置直接跑,结果死活不生效,查了半小时才发现是 shell 缓存的问题。
从那以后我每次装完 Spark,都会强制走一遍这六步验证清单,不跳步。看起来麻烦,但比出了问题再回头翻日志要省时间得多。希望帮到你。
本文还有配套的精品资源,点击获取