坑
- 注意系统和pyspark版本信息,否则导包可能出现gcc过高
- 在 Spark2.4之前,无法直接操作复杂类型(例如数组类型)
二、Spark
1、运行模式
Spark 支持多种运行模式,包括本地模式、独立模式、Mesos 模式、YARN 模式和 Kubernetes 模式。
- 本地模式:在本地模式下,Spark 应用程序会在单个机器上运行,不需要连接到集群。这种模式适用于开发和测试,但不适用于生产环境。
- 独立模式:在独立模式下,Spark 应用程序会连接到一个独立的 Spark 集群,并在集群中运行。这种模式适用于小型集群,但不支持动态资源分配。
- Mesos 模式:在 Mesos 模式下,Spark 应用程序会连接到一个 Apache Mesos 集群,并在集群中运行。这种模式支持动态资源分配和细粒度资源共享,目前国内使用较少。
- YARN 模式:在 YARN 模式下,Spark 应用程序会连接到一个 Apache Hadoop YARN 集群,并在集群中运行。这种模式支持动态资源分配和与其他 Hadoop 生态系统组件的集成,Spark在Yarn模式下是不需要Master和Worker的。
- Kubernetes 模式:在 Kubernetes 模式下,Spark 应用程序会连接到一个 Kubernetes 集群,并在集群中运行。这种模式支持动态资源分配和容器化部署。
1、宽依赖和窄依赖
窄依赖【一对一】
父 RDD 的一个分区只会被子 RDD 的一个分区依赖。比如:map/filter和union,这种依赖称之为窄依赖。
- 宽依赖【多对一】
指子RDD的分区依赖于父RDD的所有分区,这是因为shuffle类操作,称之为宽依赖。
程序首先创建了一个 SparkConf 对象,用来设置应用程序名称和运行模式。然后,它创建了一个 SparkContext 对象,用来连接到 Spark 集群
2、Spark执行流程
Spark的执行流程大致如下:
- 构建Spark Application的运行环境(启动SparkContext),SparkContext向资源管理器(可以是Standalone、Mesos或YARN)注册并申请运行Executor资源。
- 资源管理器为Executor分配资源并启动Executor进程,Executor运行情况将随着“心跳”发送到资源管理器上。
- SparkContext构建DAG图,将DAG图分解成多个Stage,并把每个Stage的TaskSet(任务集)发送给Task Scheduler (任务调度器)。
- Executor向SparkContext申请Task, Task Scheduler将Task发放给Executor,同时,SparkContext将应用程序代码发放给Executor。
- Task在Executor上运行,把执行结果反馈给Task Scheduler,然后再反馈给DAG Scheduler。
- 当一个阶段完成后,Spark 会根据数据依赖关系将结果传输给下一个阶段,并开始执行下一个阶段的任务。
- 最后,当所有阶段都完成后,Spark 会将最终结果返回给驱动程序,并完成作业的执行。
RDD特性
- 内存计算
Spark RDD运算数据是在内存中进行的,在内存足够的情况下,不会把中间结果存储在磁盘,所以计算速度非常高效。
- 惰性求值
所有的转换操作都是惰性的,也就是说不会立即执行任务,只是把对数据的转换操作记录下来而已。只有碰到action操作才会被真正的执行。
- 容错性
Spark RDD具备容错特性,在RDD失效或者数据丢失的时候,可以根据DAG从父RDD重新把数据集计算出来,以达到数据容错的效果。
- 不变性
RDD是进程安全的,因为RDD是不可修改的。它可以在任何时间点被创建和查询,使得缓存,共享,备份都非常简单。在计算过程中,是RDD的不可修改特性保证了数据的一致性。
- 持久化
可以调用cache或者persist函数,把RDD缓存在内存、磁盘,下次使用的时候不需要重新计算而是直接使用。
Spark-Submit
详细参数说明
参数名 | 参数说明 |
---|---|
—master | master 的地址,提交任务到哪里执行,例如 spark://host:port, yarn, local。具体指可参考下面关于Master_URL的列表 |
–deploy-mode | 在本地 (client) 启动 driver 或在 cluster 上启动,默认是 client |
—class | 应用程序的主类,仅针对 java 或 scala 应用 |
—name | 应用程序的名称 |
—jars | 用逗号分隔的本地 jar 包,设置后,这些 jar 将包含在 driver 和 executor 的 classpath 下 |
—packages | 包含在driver 和executor 的 classpath 中的 jar 的 maven 坐标 |
—exclude-packages | 为了避免冲突 而指定不包含的 package |
—repositories | 远程 repository |
—conf PROP=VALUE | 指定 spark 配置属性的值, 例如 -conf spark.executor.extraJavaOptions=”-XX:MaxPermSize=256m”详细参数:https://spark.apache.org/docs/latest/configuration.html |
—properties-file | 加载的配置文件,默认为 conf/spark-defaults.conf |
—driver-memory | Driver内存,默认 1G |
—driver-java-options | 传给 driver 的额外的 Java 选项 |
—driver-library-path | 传给 driver 的额外的库路径 |
—driver-class-path | 传给 driver 的额外的类路径 |
—driver-cores | Driver 的核数,默认是1。在 yarn 或者 standalone 下使用 |
—executor-memory | 每个 executor 的内存,默认是1G |
—total-executor-cores | 所有 executor 总共的核数。仅仅在 mesos 或者 standalone 下使用 |
—num-executors | 启动的 executor 数量。默认为2。在 yarn 下使用 |
—executor-core | 每个 executor 的核数。在yarn或者standalone下使用 |
./bin/spark-submit \
--master <master-url> \
--deploy-mode <deploy-mode> \
--conf <key<=<value> \
--driver-memory <value>g \
--executor-memory <value>g \
--executor-cores <number of cores> \
--py-files file1.py,file2.py,file3.zip, file4.egg \
wordByExample.py [application-arguments]
Master_URL的值
Master URL | 含义 |
---|---|
local | 使用1个worker线程在本地运行Spark应用程序 |
local[K] | 使用K个worker线程在本地运行Spark应用程序 |
local | 使用所有剩余worker线程在本地运行Spark应用程序 |
spark://HOST:PORT | 连接到Spark Standalone集群,以便在该集群上运行Spark应用程序 |
mesos://HOST:PORT | 连接到Mesos集群,以便在该集群上运行Spark应用程序 |
yarn-client | 以client方式连接到YARN集群,集群的定位由环境变量HADOOP_CONF_DIR定义,该方式driver在client运行。 |
yarn-cluster | 以cluster方式连接到YARN集群,集群的定位由环境变量HADOOP_CONF_DIR定义,该方式driver也在集群中运行。 |
转换操作 | 描述 |
---|---|
map | 将函数应用于 RDD 中的每个元素,并返回一个新的 RDD |
filter | 返回一个新的 RDD,其中包含满足给定谓词的元素 |
flatMap | 将函数应用于 RDD 中的每个元素,并将返回的迭代器展平为一个新的 RDD |
union | 返回一个新的 RDD,其中包含两个 RDD 的元素 |
distinct | 返回一个新的 RDD,其中包含原始 RDD 中不同的元素 |
groupByKey | 将键值对 RDD 中具有相同键的元素分组到一起,并返回一个新的 RDD |
reduceByKey | 将键值对 RDD 中具有相同键的元素聚合到一起,并返回一个新的 RDD |
sortByKey | 返回一个新的键值对 RDD,其中元素按照键排序 |
conf参数
- –conf spark.pyspark.python 指定引用的python版本
–conf spark.pyspark.python=/code/python_3.5.9/bin/python3.5 #注意一个问题,不建议本地安装和pyenv ,在迁移时候容易出现bug
三、PYSPARK
RDD 的创建方式
创建RDD有3种不同方式:
- 从外部存储系统
python:rdd1 = sc.textFile("hdfs://node1:8020/wordcount/input/words.txt")
saclca :val rdd1 = sc.textFile("hdfs://node1:8020/wordcount/input/words.txt")
- 从其他RDD
rdd2=rdd1.flatMap(_.split(" "))
- 由一个已经存在的 Scala 集合创建
rdd3 = sc.parallelize(Array(1,2,3,4,5,6,7,8))
1、基础
1.1、文件读取
from pyspark import SparkContext,SparkConf
from pyspark.sql import SparkSession
import sys
if __name__ == '__main__':
#配置spark环境
conf=SparkConf().setAppName("save file").setMaster("local")
sc=SparkContext(conf=conf)
#method 1
rdd=sc.textFile('dict.txt',2).map(lambda x:x.strip('\n').split())
#配置DataFrame环境
spark=SparkSession.builder.appName("to json").getOrCreate()
df=spark.createDataFrame(rdd,['id','freq','label'])
df.write.csv('data_tocsv',mode='overwrite')
df.write.json('dict_tojson',mode='overwrite')
df.write.parquet('dict_toparquet',mode='overwrite')
df.write.saveAsTable("dict_totabel")
# method 3
c_df=spark.read.option("header", "true").option("encoding", "UTF-8").text('/code/n_referer.csv')
method 1 sparkContext
# encoding=utf-8
from pyspark import SparkContext,SparkConf
from pyspark.sql import SparkSession
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
def main():
conf=SparkConf()
#conf=SparkConf().setAppName("save file").setMaster("local")
sc = SparkContext(conf=conf)
rdd = sc.textFile("/home/anyu/stat/es/access.log/2022/01/01/*.gz")
print(rdd.take(10))
if __name__ == '__main__':
main()
#run: spark-submit --master local --deploy-mode client /code/3.py
method 2 SparkSession.textFile
# encoding=utf-8
from pyspark import SparkContext,SparkConf
from pyspark.sql import SparkSession
import sys
# reload(sys)
#sys.setdefaultencoding('utf-8')
def main():
spark = SparkSession \
.builder \
.appName("ds python test") \
.getOrCreate()
# c_df=spark.read.option("header", "true").option("encoding", "UTF-8").text('/code/n_referer.csv')
T=spark.textFile("data/label.gz").count()
T.show()
if __name__ == '__main__':
main()
method 3 SparkSession.read.text
# encoding=utf-8
from pyspark import SparkContext,SparkConf
from pyspark.sql import SparkSession
import sys
# reload(sys)
#sys.setdefaultencoding('utf-8')
def main():
spark = SparkSession \
.builder \
.appName("ds python test") \
.getOrCreate()
# T=spark.textFile("data/label.gz").count()
#
# T.show()
c_df=spark.read.option("header", "true").option("encoding", "UTF-8").text('/code/n_referer.csv')
v_datafarm2=c_df.repartition(10)
v_datafarm2.show() #show(2) 只显示两行
if __name__ == '__main__':
main()
1.2、csv
读取csv
c_df=spark.read.option("header", "false").option("encoding", "UTF-8").option("sep","\\\\x01").csv('/code/33.gz')
#header设置为空,编码设置utf-8 分块使用\x01
c_df.printSchema() #查看csv的header()
1.3、执行
show()
df.show() df.show(5) #只显示5行
1.4、写入
mode:overwrite 覆盖写入
df.write.mode("overwrite").option("header", "true").csv("/path/to/csv")
四
参考链接
pyspark之统计基础操作https://blog.csdn.net/hejp_123/article/details/88033266
pyspark 高阶使用https://www.backendsite.com/index.php/193/
pyspark 写入es https://blog.csdn.net/buside/article/details/114395408