PySpark实际应用踩坑

PySpark踩坑记录

PySpark是Apache Spark支持python编写的工具,python简单实用,使用python操作spark做简单的数据分析处理也是一种选择。Cassandra是分布式NoSQL数据库系统,可以简单理解它和HBase和MongoDB类似。本文主要分享PySpark实际应用和通过PySpark操作Cassandra遇到的坑。

1. spark-cassandra-connector

首先根据spark、cassandra版本选择connector版本,参考链接:
[https://github.com/datastax/spark-cassandra-connector]

添加connector,可以在提交任务中添加:

./bin/pyspark --packages com.datastax.spark:spark-cassandra-connector_2.11:2.4.2

也可以在python脚本中添加:

os.environ["PYSPARK_SUBMIT_ARGS"] = '--packages com.datastax.spark:spark-cassandra-connector_2

2. 配置spark master和worker节点的python环境

Python版本问题首先是一个坑。
如果写代码用的python3,但是master和worker上默认python2,此时会报python运行的错误。对于用java和scala,spark-submit上传打好的jar包即可提交执行,因为driver和executor都是以JVM为载体来运行和执行任务。而对于PySpark,Spark是在外围包装一层Python API,借助Py4j实现Python和Java的交互。

因此,如果提交的脚本python版本是3,需要在master和worker节点安装python3,并在python脚本中配置节点的python路径:

os.environ["PYSPARK_PYTHON"] = '/bin/python3'
os.environ["PYSPARK_DRIVER_PYTHON"] = '/bin/python3'

此处的python路径,是master和worker节点的python路径,与上传spark任务的机器中的python路径无关。

3. PySpark操作Cassandra

比较推荐的是应用sparksql中的sparksession对象,创建spark dataset或spark dataframe。

样例如下:

from pyspark.sql import SparkSession
spark = SparkSession.builder.appName(sys.argv[0])\
    .config("spark.cassandra.connection.host", "cassandra_host_ip").getOrCreate()
# 加载Cassandra数据到dataframe
df = spark.read.format("org.apache.spark.sql.cassandra")\
    .options(table="table_name", keyspace="keyspace_name").load()
# UDF
from pyspark.sql.functions import udf
class UdfSample(object):
 ......
udf1 = udf(lambda z: UdfSample(z)......, StringType())
# dataframe写入Cassandra
df.write.format("org.apache.spark.sql.cassandra")\
    .options(table="table_name ", keyspace="keyspace_name")\
    .mode('append').save()

Dataframe中特别多的会应用udf和lambda。对于自定义udf,序列化、反序列化、及通信IO性能损耗比较明显,而Spark sql中内置的udf会降低数据在executor jvm和python worker之间序列化反序列化、通信等损耗。
spark dataframe和pandas dataframe是两种不同的数据格式,虽然有方法实现两者相互转化,但是实用性不大,且浪费资源。

4. crontab定时任务无法执行

使用spark-submit提交python脚本到spark集群,例如

./bin/spark-submit  --master spark://ip:port  ./python1.py

同样的命令手动输入运行没问题,但是在crontab上无法执行。

问题本质和crontab无关,这也是python环境的问题。如果在python脚本中加入打印sys.path的代码,会发现手动执行和crontab执行的sys.path中python路径不同。简单直接的方法是在提交命令中加入本地的python运行路径。

./bin/spark-submit 
--master spark://ip:port 
--conf spark.pyspark.python=/bin/python 
--conf spark.pyspark.driver.python=/bin/python 
./python1.py

总体来说

对于简单离线任务,可以使用PySpark快速部署提交,简单方便。但在大数据情景中,JVM和Python进程间频繁通信会导致性能损耗,尽量慎用PySpark。后续实际中遇到问题,也会继续补充。

发布了1 篇原创文章 · 获赞 0 · 访问量 82

猜你喜欢

转载自blog.csdn.net/hnudagger/article/details/104083780