手动安装 Hadoop 生态:Spark 配置与测试

想在 JupyterLab 里手动把 PySpark 跑起来(本地 / 访问 Hive / 提交到 Yarn)时读这篇

平台使用 / 在线开发
SparkpysparkfindsparkYarnyarn-clientspark-submitspark-defaultsHiveJupyterLabHadoop配置core-sitehdfs-siteyarn-site

手动安装 Hadoop 生态:Spark 配置与测试

本文是“基于已有镜像手动安装”路线的第一部分(Spark)。版本号沿用原始教程示例(Spark 3.1.3),如需与集成镜像一致请改用 README 中的版本。Flink 部分见 02-手动安装:Flink 配置与测试

一、启动基础容器

基于 ccr.ccs.tencentyun.com/cube-studio/notebook:jupyter-ubuntu-cpu-base 镜像启动 JupyterLab:

docker run --name jupyter -p 3000:3000 -p 32788-32888:32788-32888 \
    -d ccr.ccs.tencentyun.com/cube-studio/notebook:jupyter-ubuntu-cpu-base \
    jupyter lab \
    --notebook-dir=/ --ip=0.0.0.0 --no-browser --allow-root \
    --port=3000 --NotebookApp.token='' --NotebookApp.password='' \
    --NotebookApp.allow_origin='*'

注意:增加映射端口范围 32788-32888,用于下文提交 Spark 作业到 Yarn 运行。

注意:当前商业版源码使用的基础镜像名为 notebook-enterprise:jupyter-ubuntu-cpu-base(见 images/jupyter-notebook/bigdata/Dockerfile:1)。如使用商业版仓库,请把上面镜像名中的 notebook 替换为 notebook-enterprise

二、安装配置 Spark

2.1 上传 Hadoop 集群配置文件

提交 Spark 作业到 Yarn 需要 Hadoop 集群的配置文件:core-site.xmlhdfs-site.xmlyarn-site.xml。如果没有 Hadoop 集群,可参考 04-其他辅助文档 搭建单机伪分布式集群测试。

在 JupyterLab 新建 Terminal 执行:

# 新建 HADOOP_CONF_DIR 目录
mkdir -p /opt/third/hadoop/etc/hadoop/

在 Web 界面中上传 3 个 xml 到 /opt/third/hadoop/etc/hadoop/ 目录下。

注意检查 yarn-site.xml 一定要有 yarn.resourcemanager.address 配置项,否则默认值是 0.0.0.0:8032,会导致 JupyterLab 中的作业无法提交到 Yarn。示例:

<property>
    <name>yarn.resourcemanager.address</name>
    <value>xxx.xxx.xxx.xxx:8032</value>
</property>

2.2 下载配置 Spark

参考 Spark 官网,安装方式本质上有两种:一是 pip install pyspark,二是手动下载 Spark 安装包。第一种针对 Apache Spark 快速简单,但不支持其他大数据厂商的 Spark(如华为 FusionInsight、星环 TDH、Cloudera CDH)。因此本教程采用第二种,扩展性好、各厂商通用。

下载安装包

cd /opt/third

# 下载安装包
wget http://dlcdn.apache.org/spark/spark-3.1.3/spark-3.1.3-bin-hadoop3.2.tgz

# 解压,建立软连接
tar -xvzf spark-3.1.3-bin-hadoop3.2.tgz
ln -s spark-3.1.3-bin-hadoop3.2 spark

设置环境变量

vi ~/.bashrc

# hadoop
export HADOOP_CONF_DIR=/opt/third/hadoop/etc/hadoop

# spark
export SPARK_HOME=/opt/third/spark
export PATH=$PATH:$SPARK_HOME/bin
export PYTHONPATH=$(ZIPS=("$SPARK_HOME"/python/lib/*.zip); IFS=:; echo "${ZIPS[*]}"):$PYTHONPATH

source ~/.bashrc

配置 spark-defaults.conf

cd /opt/third/spark/conf
mv spark-defaults.conf.template spark-defaults.conf

# 增加 spark 作业配置项
vi spark-defaults.conf

输入以下内容:

spark.ui.enabled=false
spark.driver.port=32788
spark.blockManager.port=32789
spark.driver.bindAddress=0.0.0.0
spark.driver.host=xxx.xxx.xxx.xxx

其中 spark.driver.host 是宿主机的 IP 地址,spark.driver.portspark.blockManager.port(32788、32789)是启动容器时增加的映射端口。两个参数:

  • spark.driver.port:driver 监听来自 executor 请求的端口,executor 启动时要跟 driver 通信、获取任务信息。
  • spark.blockManager.port:driver 和 executor 进行数据传输的端口。

2.3 安装 findspark

参考 pyspark 开发环境搭建,在 notebook 中加载 spark 依赖包有三种方案:

  1. 使用 findspark 库自动识别 spark 依赖包

    import findspark
    findspark.init()
    
  2. 动态加载依赖文件

    os.environ['SPARK_HOME'] = "/opt/third/spark"
    sys.path.append("/opt/third/spark/python")
    sys.path.append("/opt/third/spark/python/lib/py4j-0.10.9-src.zip")
    
  3. 设置环境变量SPARK_HOMEPYTHONPATH(上文已设置,但在 notebook 中不生效,放弃此法)。

第二种方法对用户成本过高,因此本文采用 findspark:

pip install findspark

2.4 修改 python3 的软链接

当前 python3 -> python3.6*,要把 python3 链接到 python3.8*

cd /usr/bin
rm -rf python3
ln -s python3.8* python3

三、测试 Spark

新建 Python3 Notebook 来测试。

3.1 本地运行

import os
from random import random
from operator import add

import findspark

os.environ['SPARK_HOME'] = '/opt/third/spark'
findspark.init()

from pyspark.sql import SparkSession

if __name__ == "__main__":
    spark = SparkSession \
        .builder \
        .appName("PythonPi-Local") \
        .master("local") \
        .getOrCreate()

    n = 100000 * 2

    def f(_):
        x = random() * 2 - 1
        y = random() * 2 - 1
        return 1 if x ** 2 + y ** 2 <= 1 else 0

    count = spark.sparkContext.parallelize(range(1, n + 1), 2).map(f).reduce(add)
    print("Pi is roughly %f" % (4.0 * count / n))

    spark.stop()

3.2 本地运行访问 Hive

import os
import findspark

os.environ['SPARK_HOME'] = '/opt/third/spark'
findspark.init()

from pyspark.sql import SparkSession

if __name__ == "__main__":
    spark = SparkSession.builder \
        .appName('spark-hive-demo') \
        .config("hive.metastore.uris", "thrift://xxx.xxx.xxx.xxx:9083") \
        .enableHiveSupport() \
        .getOrCreate()

    spark.sql("create table if not exists demo(id bigint,name String)")

    spark.sql("insert overwrite demo values (1,'hamawhite'),(2,'song.bs')")
    spark.sql("select * from demo").show()

其中 xxx.xxx.xxx.xxx:9083 是 Hive MetaStore 的地址。

3.3 Yarn-client 模式运行 jar 作业

命令行模式测试 spark jar 作业,确保容器、spark、yarn 的配置都正确:

cd /opt/third/spark

# 运行作业
spark-submit --class org.apache.spark.examples.SparkPi \
    --master yarn \
    --deploy-mode client \
    --driver-memory 4g \
    --executor-memory 2g \
    --executor-cores 1 \
    --queue default \
    examples/jars/spark-examples*.jar \
    10

可以在 Yarn Web 界面上看到提交过去的作业。

3.4 Yarn-client 模式运行 pyspark 作业

import os
import sys
from random import random
from operator import add

import findspark

os.environ['SPARK_HOME'] = '/opt/third/spark'
os.environ['HADOOP_CONF_DIR'] = '/opt/third/hadoop/etc/hadoop'

findspark.init()

from pyspark.sql import SparkSession

if __name__ == "__main__":
    spark = SparkSession \
        .builder \
        .appName("PythonPi-Yarn-Client") \
        .master("yarn") \
        .config("spark.submit.deployMode", "client") \
        .getOrCreate()

    n = 100000 * 2

    def f(_):
        x = random() * 2 - 1
        y = random() * 2 - 1
        return 1 if x ** 2 + y ** 2 <= 1 else 0

    count = spark.sparkContext.parallelize(range(1, n + 1), 2).map(f).reduce(add)
    print("Pi is roughly %f" % (4.0 * count / n))

    spark.stop()

可以在 Yarn Web 界面上看到提交过去的作业。

Yarn 提交的作业

最后更新 2026-07-09完整文档以官方仓库为准:GitHub Wiki