PySpark 单机版(含spark-submit)

PySpark 单机版(含spark-submit)

前提条件

JDK 1.8
Python 3.7

下载Spark2

https://spark.apache.org/downloads.html
https://archive.apache.org/dist/spark/spark-2.4.8/spark-2.4.8-bin-hadoop2.7.tgz

安装Spark2

# 0. 创建安装路径
sudo mkdir -p /opt/modules
sudo chown -R `id -u`:`id -g` /opt/modules

# 1. 解压部署
tar -xf spark-2.4.8-bin-hadoop2.7.tgz -C /opt/modules
cd /opt/modules && mv spark-2.4.8-bin-hadoop2.7 spark-2.4.8

# 2. 减少日志输出,可选
cd /opt/modules/spark-2.4.8/conf && cp log4j.properties.template log4j.properties  
vi log4j.properties  # 进行以下修改
## log4j.rootCategory=INFO, console 修改为
## log4j.rootCategory=WARN, console

检验Spark2

# 1. spark-sql
cd /opt/modules/spark-2.4.8 && bin/spark-sql
## spark-sql> show databases;
## default
## Time taken: 1.972 seconds, Fetched 1 row(s)
## spark-sql> quit;

# 2. spark-submit
cd /opt/modules/spark-2.4.8 &&\
  bin/spark-submit examples/src/main/python/pi.py
## Pi is roughly 3.142200
## spark-submit 执行Python 脚本时,它默认会调用Python 2.7 如果没有则报错
## Cannot run program "python": error=2, No such file or directory
## 参考,https://spark.apache.org/docs/2.4.8/configuration.html,解决办法如下
## 方法1,Simple Command,一次性的
PYSPARK_PYTHON=python3 bin/spark-submit examples/src/main/python/pi.py
## 方法2,将以下内容写入~/.bashrc 或~/.zshrc.pre-oh-my-zsh,永久的
export PYSPARK_PYTHON=python3
### 之后记得用source 命令让配置生效,然后就可以直接执行spark-submit 了
source ~/.zshrc.pre-oh-my-zsh
bin/spark-submit examples/src/main/python/pi.py

PySpark 开发

Spark2 单机版说明

由于是纯单机版,所以本例的Spark默认使用自带的HiveDerby管理元数据,且数据文件都存储在本地磁盘
例如执行cd /opt/modules/spark-2.4.8 && bin/spark-sql
其就会在/opt/modules/spark-2.4.8当前路径下生成

  1. 一个文件:derby.log,记录了derby数据库的相关日志信息,可通过JVM参数derby.system.home指定路径
  2. 一个目录:metastore_dbderby用于记录元数据的数据库,可通过JVM参数derby.system.home指定路径
  3. 一个目录:spark-warehouse,真正存储数据的地方,可通过 spark.sql.warehouse.dir修改存储路径
    参考,https://spark.apache.org/docs/2.4.8/sql-data-sources-hive-tables.html
    特别注意metastore_dbspark-warehouse,后面开发会用到

metastore_db 路径修改

spark-warehouse 路径修改

上面说到derby.logmetastore_db在执行Spark程序的当前路径下生成,不方便管理,需要指定一个集中的地方

# 修改Spark 默认配置文件
vi /opt/modules/spark-2.4.8/conf/spark-defaults.conf
# 添加以下内容
spark.sql.warehouse.dir        /opt/modules/localfs/warehouse
spark.driver.extraJavaOptions  -Dderby.system.home=/opt/modules/metastore
## 修改后,将会在/opt/modules/metastore 下生成`derby.log`和`metastore_db`
## 而`数据库`和`没有指定存储路径`的`外部表`将会存储在/opt/modules/localfs/warehouse

示例程序数据准备

-- 启动Spark-SQL 交互终端
-- cd /opt/modules/spark-2.4.8 && bin/spark-sql

create database if not exists temp_db;
use temp_db;

drop table if exists t01;
create external table t01 (
    uid int,
    uname string
) partitioned by (dt string)
stored as parquet
location '/opt/modules/localfs/new/t01'
;

insert overwrite table temp_db.t01 partition (dt='2022-09-10') 
values (1, 'AAA'), (2, 'BBB'), (3, 'CCC'), (4, 'DDD');

select * from temp_db.t01;

通过spark-submit 提交

测试程序01

/tmp目录下创建t01.py,内容如下

cat > /tmp/t01.py << 'EOF'
from pyspark.sql import SparkSession

#metastore_path = "jdbc:derby:;databaseName=/opt/modules/spark-2.4.8/metastore_db"
metastore_path = "jdbc:derby:;databaseName=/opt/modules/metastore/metastore_db"

spark = SparkSession.builder.master("local[2]").appName("test")\
            .config("javax.jdo.option.ConnectionURL", metastore_path)\
            .enableHiveSupport()\
            .getOrCreate()

spark.sql("show databases").show()
spark.sql("use temp_db")#.show()
spark.sql("show tables").show()
read_df = spark.sql("select * from temp_db.t01 limit 10")
read_df.show()

spark.stop()

EOF
提交测试程序
# 因为Derby 只支持单用户,所以提交前先确认没有别的Spark 程序在本机运行
cd /opt/modules/spark-2.4.8 && bin/spark-submit /tmp/t01.py

# 执行结果如下
+------------+
|databaseName|
+------------+
|     default|
|     temp_db|
+------------+

+--------+---------+-----------+
|database|tableName|isTemporary|
+--------+---------+-----------+
| temp_db|      t01|      false|
+--------+---------+-----------+

+---+-----+----------+
|uid|uname|        dt|
+---+-----+----------+
|  3|  CCC|2022-09-10|
|  4|  DDD|2022-09-10|
|  1|  AAA|2022-09-10|
|  2|  BBB|2022-09-10|
+---+-----+----------+

python3 运行pyspark

创建测试环境
# 1. 创建虚拟环境
python3 -m venv ts01

# 2. 激活虚拟环境
cd ts01 && source bin/activate

# 后面测试结束之后
# 3. 退出虚拟环境
deactivate

# 4 删除虚拟环境
cd .. && rm -rf ts01

引入PySpark
# 相当于手动 pip3 install pyspark,即然Spark 安装包里有就直接用了
cd lib/python3.7/site-packages/ &&\
cp /opt/modules/spark-2.4.8/python/lib/{py4j-0.10.7-src.zip,pyspark.zip} . &&\
unzip py4j-0.10.7-src.zip && unzip pyspark.zip &&\
rm -rf py4j-0.10.7-src.zip pyspark.zip

# 检验是否成功引入PySpark
python3 <(echo from pyspark.sql import SparkSession)
## 什么都不显示即没有报错就表示成功
测试程序02

/tmp目录下创建t02.py,内容如下

cat > /tmp/t02.py << 'EOF'
from pyspark.sql import SparkSession

# 这里指定环境变量让程序可以直接运行
import os
os.environ['SPARK_HOME'] = '/opt/modules/spark-2.4.8'
os.environ['PYTHONPATH'] = '/opt/modules/spark-2.4.8/python'
#os.environ["PYSPARK_PYTHON"] = "/Library/Frameworks/Python.framework/Versions/3.7/bin/python3"

spark = SparkSession.builder.master("local[2]").appName("test")\
        .config("javax.jdo.option.ConnectionURL", "jdbc:derby:;databaseName=/opt/modules/metastore/metastore_db")\
        .enableHiveSupport().getOrCreate()

spark.sql("show databases").show()
spark.sql("use temp_db")
spark.sql("show tables").show()
spark.sql("""
        insert overwrite table temp_db.t01 
        partition(dt='2022-09-30')
        values (5, 'EEE'), (6, 'FFF')
""")
read_df = spark.sql("select * from t01 limit 10")
read_df.show()

spark.stop()

EOF
执行测试程序
# 因为Derby 只支持单用户,所以提交前先确认没有别的Spark 程序在本机运行
# 注意要在之前创建的虚拟环境ts01 下执行,因为那里面配置了pyspark 的依赖
python3 /tmp/t02.py

# 执行结果如下
+------------+
|databaseName|
+------------+
|     default|
|     temp_db|
+------------+

+--------+---------+-----------+
|database|tableName|isTemporary|
+--------+---------+-----------+
| temp_db|      t01|      false|
+--------+---------+-----------+

+---+-----+----------+
|uid|uname|        dt|
+---+-----+----------+
|  3|  CCC|2022-09-10|
|  4|  DDD|2022-09-10|
|  1|  AAA|2022-09-10|
|  2|  BBB|2022-09-10|
+---+-----+----------+

常见错误

Cannot run program “python”: error=2, No such file or directory

## 参考,https://spark.apache.org/docs/2.4.8/configuration.html,解决办法如下
## 方法1,Simple Command,一次性的
PYSPARK_PYTHON=python3 bin/spark-submit examples/src/main/python/pi.py
## 方法2,将以下内容写入~/.bashrc 或~/.zshrc.pre-oh-my-zsh,永久的
export PYSPARK_PYTHON=python3
### 之后记得用source 命令让配置生效,然后就可以直接执行spark-submit 了
source ~/.zshrc.pre-oh-my-zsh
bin/spark-submit examples/src/main/python/pi.py
## 方法3,在程序中加上环境变量
os.environ["PYSPARK_PYTHON"] = "/Library/Frameworks/Python.framework/Versions/3.7/bin/python3"

Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient

Derby只支持一个客户端连接,开启了多个spark-sql实例就会报改错误异常,提交任务前确保没有其他实例在本机运行

参考资料

Spark系列/PySpark/PyCharm 开发pyspark.md
Spark:Hive on Spark 单机版元数据管理
Spark Configuration 环境变量和配置参数
Spark SQL Hive Tables
Hive 的安装及配置,本机Derby 路径
Python3 虚拟环境和包
Spark运行时自定义derby.log和metastore_db的生成路径

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值