Spark2.X学习(1) - 结构化API概述(DataFrame与DataSet)

本系列笔记主要参考《Spark权威指南2.X》,主要学习在Spark2.X中的DataFrame和DataSet等结构化API。

一些Spark的基础知识,可以参考之前我断断续续的学习笔记:《Spark快速大数据分析》- Spark应用运行原理

1. 结构化API简介

Spark中的结构化API主要指DataSet类型、DataFrame类型、SparkSQL表与视图。

一个使用结构化API的Spark程序一般包括以下几步:

  • SparkSQL等方式读入数据,得到DataSet或DataFrame类型的输入
  • 对输入通过DataSet或DataFrame类型的API或SparkSQL做转化操作[Transformation],得到新的DataSet或DataFrame类型数据
  • 对数据做动作操作[Action](如count、collect、写操作等),Spark生成物理执行计划开始执行
1.1 DataSet与DataFrame

在Spark1.3之前的版本,Spark的基本数据结构是RDD,其优缺点都比较明显:

  • 提供了很多函数操作,如map,filter等,可以方便地处理结构化或非结构化数据,适用于各种场景

  • 直接存储java对象,面向对象编程,是类型安全的

  • 存储对象的数据结构对RDD是黑盒,要处理某一列数据时难以优化,性能较低

  • 默认采用的是java序列化方式,序列化结果比较大,数据存储在java堆内存中,导致gc比较频繁影响性能

img

Spark1.3开始引入DataFrame类型,DataFrame可以理解成【RDD[Row]+schema】,即DataFrame中存储的对象是Row,同时Spark存储Row的schema信息。如上图所示,在RDD中,只知道是Person,而在DataFrame中,Spark知道每个Row包含Name、Age、Height三个信息。

  • 对结构化数据的处理很方便,支持Hive、mysql等传统数据表,也支持KV数据
  • 由于数据结构元信息已保存,易于优化,性能较高,如只需处理Age那一列数据时,RDD需要整个Person的数据,DataFrame则可以只取Age一列数据
  • 序列化时不需要带上元信息,大大的减少了序列化大小,而且数据保存在堆外内存中,减少了gc次数

DataSet,是类型安全的DataFrame,即DataSet类通过内部包含的对象类型参数化,如DataSet[Person],表示其每个数据都是Person对象,同时包含其schema信息。

DataSet用于在Java和Scala中编写静态类型的代码,在Python中不可用,因为Python是动态类型的。

DataSet整合了RDD和DataFrame的优点:

  • 支持面向对象编程,支持结构化数据与非结构化数据
  • 支持结构化数据的SQL操作,采用堆外内存存储,GC友好
  • 类型安全
1.2 行、列、模式与Spark类型

DataFrame是无类型的Dataset,即Dataset[Row](这里的无类型是指Spark仅在运行时检查类型是否与schema指定的类型一致,相对地,Dataset在编译时就会检查类型是否符合规范)。

在使用DataFrame和Dataset前,先简单介绍其中的一些主要概念——

  • 行(Row):一行是一个数据记录,如上所说,DataFrame的每个记录都是Row类型,Row类型是Spark用于支持内存计算而优化的数据格式,有利于高效计算(此处来自书中,不知道原因)
  • 列(column):列是一个表达式,可以在Dataset中每个单独的记录上执行的计算表达式
  • 模式(schema):模式定义了DataFrame的列名以及列的数据类型,也就是数据表中的元信息
  • Spark类型:Spark有大量的内部类型表示,使用不同的语言开发Spark程序,在执行时会转化为对应的Spark类型,如StringType、LongType等

2. 结构化API执行逻辑

一个结构化API查询任务,可简单划分为以下过程:

  • 编写SparkSQL/DataFrame/Dataset代码
  • Spark的Catalyst优化器将代码解析为语法树、转化为逻辑执行计划、对执行计划进行优化并最终转化为物理执行计划
  • Spark在集群上执行该物理执行计划(多个RDD操作)
    在这里插入图片描述

其中第二步中Catalyst完成的任务,可参考Spark中的Catalyst,有非常详细的解释和例子,这里对文中的内容做摘抄和简单的总结。

img

如上图所示,Spark的Catalyst执行过程包含以下4个步骤:

(1) Parser:Parser模块将代码解析为语法树,得到的语法树称为Unresolved Logical Plan,是逻辑计划的框架,但对计划中的people、score还无法理解

  • Analyzer:Parser解析后,Analyzer遍历整个语法树,利用Catalog(所有表和DataFrame信息的存储库)将每个节点进行数据类型绑定、函数绑定,得到逻辑执行计划Logical Plan

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O2eY2wZj-1608978141022)(/image-20201226181034853.png)]

  • Optimizer:优化器是整个Catalyst的核心,优化器有基于规则优化基于代价优化,以基于规则优化为例,对语法树进行遍历,模式匹配能够满足规则的节点,在进行相应的等价转换。常见的规则有谓词下推(Predicate Pushdown,即将过滤条件提前)、常量累加(Constant Folding,合并常量运算,如a+1+2变成a+3)和列值裁剪(Column Pruning,只保留需要使用的列)

  • Physical Planning:此时已经得到优化后的逻辑执行计划,将逻辑执行计划中的算子指定相应的算法策略,如Join算子,有BroadcastHashJoin、ShuffleHashJoin以及SortMergeJoin,在这些具体实现中基于代价比较,挑选一个合适的算法实现,就可以得到物理执行计划

至此,Catalyst将结构化查询任务转化为物理执行计划,执行计划实际上是一系列的RDD和转换操作,Spark将所有代码运行在Spark的底层编程接口RDD上。

Reference

  1. 《Spark权威指南2.X》

  2. Spark中的RDD、DataFrame、Dataset对比

  3. Spark中的Catalyst

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值