Apache Spark是一个在集群上运行的统一计算引擎以及一组并行数据处理软件库。
Spark的下载链接
学习资源,代码及数据链接
1.Spark应用程序
Spark应用程序由一个驱动器进程和一组执行器进程组成。
驱动进程运行mian()函数,位于集群中的一个节点上:
- 维护Spark应用程序的相关信息;
- 回应用户的程序或输入;
- 分析任务并分发给若干执行器进行处理
执行器负责执行驱动器分配给它的实际计算工作:
- 执行驱动器分配给他的代码;
- 将执行器的计算状态报告给驱动器的节点。
SparkSession与支持Saprk API编程语言的关系
在目录bin下,运行pyspark
2.DataFrame
DataFrame:包含行和列的数据表
- 数据分区:Spark将数据分解成多个数据块,每个数据块叫做一个分区。分区是位于集群中的一台物理机上的多行数据集合,DataFrame的分区说明在执行过程中数据在集群中的物理分布。如果只有一个分区,即使有上千个执行器,Spark也只有一个执行器在处理数据。同样,有多个分区,只有一个执行器,Spark仍然只有一个执行器在处理数据。
- 转换操作:Spark核心数据结构在计算过程中是保持不变的,修改执行想要的操作称为转换。
eg:执行转换来找到所有偶数
divisBy2 = myRange.where("number%2 =0")
转换并没有实际输出,只是指定了一个抽象转换。
两种转换操作:窄依赖关系(每个输入分区仅决定一个输出分区的转换,自动执行流水线处理,指定了多个过滤操作)、宽依赖关系(每个输入分区决定了多个输出分区,shuffle操作,会在整个集群中执行互相交换分区数据的功能,将结果写入磁盘)
- 惰性评估:等到绝对需要时才执行计算。在Spark中,当用户表达一些对数据的操作时,不是立即修改数据,而是建立一个作用到原始数据的转换计划。Spark首先会将这个计划编译为可在集群中高效运行的流水线式的物理执行计划,然后等待,直到最后时刻才开始执行代码。例子:DataFrame的谓词下推(predicate pushdown),假设我们构建一个含有多个转换操作的Spark作业,并在最后指定了一个过滤操作,假设这个过滤操作只需要数据源中的某一行数据,则最有效的方法是在最开始仅访问我们需要的单个记录,Spark会通过自动下推这个过滤操作来优化整个物理执行计划。
- 动作操作:触发计算,运行一个操作工作。一个动作指示Spark在一系列转换操作后计算一个结果。
- spark用户接口:通过Spark的Web UI监控一个作业的进度,Spark UI占用驱动器节点4040端接口。如果在本地模式下运行,可通过http://localhost:4040/访问。
3.一个完整的例子
1.从文件中读取数据(执行一种被称作模式推理的操作,让Spark猜测DataFrame的模式,并指定文件的第一行为文件头)
flightData2015 = spark.read.option("inferSchema","true").option("header","true").csv("d://spark/data/flight-data/csv/2015-summary.csv")
2.显示文件前3行数据
flightData2015.take(3)
3.根据count列的值排序,操作并不会修改DataFrame,因为sort是一个转换。
调用某个DataFrame的explain操作会显示DataFrame的来源
4.指定一个动作来触发计划的执行,首先完成一个配置,默认情况下,shuffle操作会输出200个shuffle分区,我们设置为5
>>> spark.conf.set("saprk.sql.shuffle.partitions","5")
>>> flightData2015.sort("count").take(2)
4.DataFrame和SQL
使用Spark SQL,可以将人和DataFrame注册为数据表或视图,并且使用纯SQL对它进行查询。编写SQL查询或DataFrame代码并不会造成性能差异,它们都会被“编译”成相同底层执行计划。
分别使用Spark SQL 方法和DataFrame方法查询,计划编译后是完全相同的基本执行计划。
DataFrame转换的完整流程
每个转换产生一个新的不可变的DataFrame,可以在这个DataFrame上调用一个动作来产生一个结果
from pyspark.sql.funtions import desc
flightData2015.groupBy("DEST_COUNTRY_NAME").sum("count").withColumnRenamed("sum(count)","destination_total").sort(desc("destination_total")).limit(5).show()
- 读取数据。但没有真正读取,直到调用动作操作后才会真正读取。
- 分组。当调用groupBy时,得到RelationalGroupedDataset对象,是一个DataFrame对象,具有指定的分组,但需要用户指定聚合操作,然后才能进一步查询。按键分组,然后再对每个键对用分组进行聚合操作。
- 聚合指定。使用sum聚合操作,需要一个表达式或者一个列的名称。sum方法调用产生一个新的DataFrame,它有一个新的表结构,并知道每个列的类型。还是没有执行计算
- 简单的重命名。带有两个参数的withColumnRenamed方法,原始列名称和新列名称。
- 对数据进行排序。获得值较大的一些行作为动作结果。
- 指定一个限制。只想返回DataFrame中前5个值
- 执行动作。
解释计划:
5.Spark工具集介绍
- 运行生产应用程序:spark-submit将应用程序代码发送到一个集群并在那里执行,直到它完成正确退出或遇到错误。
- Dataset:类型安全的结构化API
- 结构流处理:可以减少延迟并允许增量处理,快速地从流式系统中提取有价值的信息。
- 机器学习和高级数据分析:MLlib支持对数据进行预处理、整理、模型训练和大规模预测。
- 低级API
- Spark R