最近后台收到不少私信,问的问题高度集中在几类:Spark代码到底该怎么写、一跑就OOM怎么调、集群搭起来之后怎么验证是否正常、Spark到底能不能直接读Redis和数据库。这些问题看着零散,其实都指向同一个根本诉求:在实际项目里把Spark用起来,并且用对、用好。
这篇内容不打算给你贴一个过于简单的Hello World,而是把我在多个数据平台上跑Spark任务时沉淀下来的代码模式、环境搭建细节和排障经验一次性整理出来。不管你是数据分析师想处理单机跑不动的数据,还是后端工程师要维护Spark集群,又或者是在准备Spark方向面试的开发,这篇文章都能给你一些可以直接落到代码里的东西。
1. 先搞懂Spark代码和普通Python脚本的本质区别
很多人第一次接触Spark时,会下意识地把它当成"大号pandas"。这种理解会在后续写代码时埋下很多坑,因为Spark的底层执行逻辑和单机脚本完全不是一回事。
1.1 惰性求值才是Spark代码的灵魂
以pandas为例,你用pd.read_csv("logs.csv")读文件,数据会立刻被加载进内存,后续的groupby、merge、agg都是马上执行、马上出结果。这种模式叫急切执行(eager execution)。
Spark则完全不同。看这段代码:
python复制from pyspark.sql import SparkSession
spark = SparkSession.builder.appName("demo").getOrCreate()
df = spark.read.csv("hdfs://logs/2025/", header=True)
filtered = df.filter(df["level"] == "ERROR")
result = filtered.groupBy("hour").count()
result.show()
当你执行read.csv、filter、groupBy时,Spark并没有真正去读文件、过滤数据,它只是把这些操作记录成一棵逻辑执行计划树。直到你调用show()或write这类行动操作(action)时,Spark才会基于这棵逻辑树生成物理执行计划,再把任务分发到各节点执行。
这个机制叫惰性求值(lazy evaluation)。理解这一点,你才能真正理解为什么Spark代码有时候"看着很慢"——你以为它在读数据,其实它只是构建了计划。反过来,这也是Spark能做很多自动优化的前提,比如谓词下推、列剪枝,都是在生成物理计划阶段根据整条计算链来完成的。
1.2 分区决定性能上限,代码决定逻辑正确性
Spark把数据切分成多个分区(partition),每个分区由集群中一个Executor上的一个Task来处理。分区的数量直接影响并行度和最终性能。
举个例子,如果一份100GB的数据只有一个分区,那Spark只会启动一个Task来处理它,即便Executor资源再充足,并行度也上不去。反过来,如果分区数过多,每个Task处理的数据量太小,调度和序列化开销反而会占大头,任务同样快不起来。
我之前接手过一个Spark任务,处理前一天的订单数据,数据量不大,但集群有64核。原始代码用默认分区跑,整个任务耗时22分钟。我加了repartition(64)之后,耗时直接降到6分钟。没有改任何业务逻辑,仅仅是把并行度从默认值拉到了与CPU核数匹配的水平。
写Spark代码时,先问自己三个问题:
- 数据量有多大,分区数应该设置成多少?
- 每个Task需要处理的数据量是否合理?
- 数据在节点间的分布是否会引发严重的网络传输?
这三个问题想清楚了,基本就能避免后期大量调优工作。代码本身的逻辑正确性只是第一步,分区和并行度才是Spark代码性能的分水岭。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从零搭建Spark运行环境:安装、集群配置与第一个作业
热搜词里"spark集群搭建"和"spark安装详细步骤"都排得很靠前,说明动手第一步就拦住了一批人。我尽量把从零到能跑通第一个作业的路径给你理顺。
2.1 安装前的版本选择与前置条件
Spark本身依赖Java运行环境,所以第一步一定是先装JDK。目前Spark 3.x系列对JDK 8和JDK 11都支持,但不同小版本支持的细节略有差异。我建议直接用JDK 8或JDK 11,这俩在社区里验证最充分,遇到问题搜到的解决方案最多。
版本选择上,除非你有特殊需求,否则不要追最新版本,直接选当前最新的稳定版本即可。以Spark 3.5.x为例,它对应兼容的Hadoop版本是3.3.x系列。如果你需要对接Hive,还要确保Spark和Hive的版本兼容,否则后面跑spark.sql查Hive表时会踩一堆metastore的兼容问题。
安装步骤大致如下:
- 下载Spark安装包,解压到指定目录,比如
/opt/spark。 - 配置环境变量,在
~/.bashrc或/etc/profile里加上SPARK_HOME和PATH。 - 修改
$SPARK_HOME/conf/spark-env.sh,设置JAVA_HOME。 - 用
spark-shell或pyspark启动一个本地实例验证安装是否成功。
bash复制tar -zxvf spark-3.5.0-bin-hadoop3.tgz
mv spark-3.5.0-bin-hadoop3 /opt/spark
cat >> ~/.bashrc <<EOF
export SPARK_HOME=/opt/spark
export PATH=$SPARK_HOME/bin:$PATH
EOF
source ~/
