Spark相关内容
1.spark程序与pySpark交互流程
给你一个图
2.Spark-Submit相关参数
spark-submit 命令作用:
用于将spark程序提交指定的资源调度平台上进行运行,
并且提交的过程中可以对资源,任务进行相关设置
'相关的参数:
--master
--deploy-mode
--conf
'
Driver资源参数:
executor资源参数:
3 RDD相关内容
3.1 什么是RDD?
RDD:**弹性分布式数据集**
RDD出现的目的:主要用于支持迭代计算,并且提升迭代计算的效率
背景说明:
早期我们的计算模型: 单机模型
比如: pandas, mysql
适用于: 少量数据集统计分析处理
在计算过程中, 数据在一个进程中, 不断的进行各种迭代计算
当数据量大了之后, 单机计算模型可能无法支撑, 此时需要分布式计算模型:
核心: 让多个节点参与计算, 将计算任务进行划分, 交给各个节点进行运行, 运算后, 将结果汇总即可
比如: MapReduce, spark
mapreduce计算模式:
在计算过程中, 每一个MR都是由两部分组成: map 和 reduce
在计算过程中, 需要将数据从磁盘读取内存, 从内存落入到磁盘, 在从磁盘到内存, 导致IO增大,效率降低
由于一个MR中只有map 和reduce两个阶段, 如果涉及到需要进行迭代计算的时候, 单个MR是无法实现, 此时就需要将MR进行串联
正因为MR出现这种问题, 此时想办法解决这种问题, 解决方案思路:
1) 是否可以将中间计算结果都保存内存中, 这也是导致基于线程运行模型方案
2) 支持更好迭代计算:
在一个进程中, 让多个线程产生先后执行(产生多个stage), 先后执行中间一般判断的标准是否有shuffle, 第一个阶段中各个线程进行并行的计算执行, 将执行结果保存到内存中,然后执行第二个阶段. 直接从内存中读取第一个阶段的结果, 然后执行运行 ...
而这种方案就产生一个数据结构: RDD
MR迭代计算流程:
SPARK的迭代计算
3.2 RDD的五a大特性:
-
(必须具备)可分区的
-
(必须具备)计算函数(对每个分区进行计算操作)
-
(必须具备)存在依赖 (上一步每执行完 下一步无法执行 需要上一步的结果)
-
(可选)对于key-value数据存在分区计算函数
-
(可选)移动数据不如移动计算(将计算程序运行在离数据越近越好) —距离优化
其中前3个特性是每一个RDD对象都具备的 后两项是可选的
3.3 RDD的五大特点 (了解)
1. 可分区的:RDD分区的抽象分区 定义分区的规则 没有真实的分区
2. 只读:一个RDD对象中数据是不可变的
3. 依赖: RDD与RDD之间是存在依赖关系:依赖关系越长,整个血缘关系越长
依赖中分为宽依赖和窄依赖
4. 缓存:当需要对一个RDD的结果重复使用的时候,可以将这个RDD的结果缓存起来,减少重新计算的资源和时间消耗
数据是缓存在executor的内存中
5.checkpoint:检测点
当依赖关系比较长的时候,如果其中的一个RDD算子执行失败,此时如果再次执行,需要重建血缘关系(重新将之前的所有流程全部重新执行一次),此时可以通过checkpoint对各个阶段RDD结果数据保存在磁盘上,一旦失败后,可以直接从某一阶段的checkpoint检查点进行回复数据,这样无需再重建血缘关系。
4.如何构建RDD
构建RDD主要有两种形式
通过并行化方式构建:paralleliz(。。。。。)
通过加载外部数据源的方式构建 textFile(。。。。。。)
4.1通过并行化的方式来构建RDD
固定格式:
from pyspark import SparkCountext, SparkConf
import os
'目的:锁定远端操作环境,避免存在多个版本环境的时候,可能会出问题 '
os.environ["SPARK_HOME"] ="/export/server/spark"
os.environ["PYSPARK_PYTHON"]="/root/anaconda3/bin/python"
os.environ["PYSPARK_DRIVER_PYTHON"] ="/root/anaconda3/bin/python"
'函数窗口'
if __name__ == '__main__':
# 1)创建 SparkCountext 函数上下文对象 setAppName定义线程名称 本地模式运行
spark_conf = SparkConf().setAppName("dome1").setMaster("local[*]")
spark_context = SparkCountext().getOrCreate(conf=spark_conf)
#演示RDD创建方式一:并行
rdd_par = spark_context.parallelize(["张三","李四","王五"],5)
#如何查其有多少个分区?
print(rdd_par.getNumPartitions())
#如何查看每个分区下有哪些数据?
print(rdd_par.golm.collect())
说明:' parallelize 将python的列表(集合,字典)转换为一个spark的RDD对象 '
适用于:' 测试中 初始本地数据集 '
运行结果:
涉及相关API:
1) 如何查看当前数据集有多少个分区:
rdd.getNumPartitions()
2) 如何查看每一个分区下的数据
rdd.glom().collect()
4.2 通过外部数据方式构建RDD
from pyspark import SparkContext, SparkConf
import os
# 目的: 锁定远端操作环境, 避免存在多个版本环境的时候, 可能会出问题
os.environ["SPARK_HOME"] = "/export/server/spark"
os.environ["PYSPARK_PYTHON"] = "/root/anaconda3/bin/python"
os.environ["PYSPARK_DRIVER_PYTHON"] = "/root/anaconda3/bin/python"
if __name__ == '__main__':
print("hello pySpark")
----------------------------------------------------------------------------
#构建SparkCountext对象
spark_conf=SparkConf().setAppName("dome2").setMaster("spark://192.168.xx.xxx:7077,192.|168.xx.xxx:7077")
#2)RDD创建方式二:通过加载外部数据源方式创建 textFile
#注意:此处本地路径指的是LiunX本地路径
rdd_textFile = SparkContext.textFile("file:///demo/data/")
print(rdd_textFile.getNumPartitions())
---------------------------------------------------------------------------
结果返回:4
我在data这个文件夹下有四个小文件 可以发现 返回的分区数 正对应文件数
一个文件至少会被分为一个分片, 但是如果有大量的小文件, 此时分片过多, 导致资源占比比较高
有什么解决方法呢? wholeTextFiles()
from pyspark import SparkContext, SparkConf
import os
# 目的: 锁定远端操作环境, 避免存在多个版本环境的时候, 可能会出问题
os.environ["SPARK_HOME"] ="/export/server/spark"
os.environ["PYSPARK_PYTHON"]="/root/anaconda3/bin/python"
os.environ["PYSPARK_DRIVER_PYTHON"] ="/root/anaconda3/bin/python"
if __name__ == '__main__':
# 1) 创建sparkContext 上下文对象
spark_conf = SparkConf().setAppName("_02_main").setMaster("spark://node1:7077,node2:7077")
spark_context= SparkContext().getOrCreate(conf=spark_conf)
--------------------