1.Spark SQL 概述
1.1 什么是 Spark SQL
Spark SQL 是 Spark 用来处理结构化数据的一个模块,它提供了 2 个编程抽象:DataFrame 和
DataSet,并且作为分布式 SQL 查询引擎的作用。
我们已经学习了 Hive,它是将 Hive SQL 转换成 MapReduce 然后提交到集群上执行,大大简
化了编写 MapReduc 的程序的复杂性,由于 MapReduce 这种计算模型执行效率比较慢。所有 Spark
SQL 的应运而生,它是将 Spark SQL 转换成 RDD,然后提交到集群执行,执行效率非常快!
1.2 Spark SQL 的特点
1)易整合
![](https://img2018.cnblogs.com/blog/1604514/201907/1604514-20190708025734696-958769414.png)
2)统一的数据访问方式
![](https://img2018.cnblogs.com/blog/1604514/201907/1604514-20190708025753432-1083260364.png)
3)兼容 Hive
![](https://img2018.cnblogs.com/blog/1604514/201907/1604514-20190708025818897-1499501559.png)
4)标准的数据连接
1.3 什么是 DataFrame
与 RDD 类似,DataFrame 也是一个分布式数据容器。然而 DataFrame 更像传统数据库的二维
表格,除了数据以外,还记录数据的结构信息,即 schema。同时,与 Hive 类似,DataFrame 也支
持嵌套数据类型(struct、array 和 map)。从 API 易用性的角度上看,DataFrame API 提供的是一
套高层的关系操作,比函数式的 RDD API 要更加友好,门槛更低。
上图直观地体现了 DataFrame 和 RDD 的区别。左侧的 RDD[Person]虽然以 Person 为类型参
数,但 Spark 框架本身不了解 Person 类的内部结构。而右侧的 DataFrame 却提供了详细的结构信
息,使得 Spark SQL 可以清楚地知道该数据集中包含哪些列,每列的名称和类型各是什么。
DataFrame 是为数据提供了 Schema 的视图。可以把它当做数据库中的一张表来对待,DataFrame
也是懒执行的。性能上比 RDD 要高,主要原因:
优化的执行计划:查询计划通过 Spark catalyst optimiser 进行优化。比如下面一个例子:
![](https://img2018.cnblogs.com/blog/1604514/201907/1604514-20190708030024586-268956297.png)
为了说明查询优化,我们来看上图展示的人口数据分析的示例。图中构造了两个 DataFrame,
将它们 join 之后又做了一次 filter 操作。如果原封不动地执行这个执行计划,最终的执行效率是
不高的。因为 join 是一个代价较大的操作,也可能会产生一个较大的数据集。如果我们能将 filter
下推到 join 下方,先对 DataFrame 进行过滤,再 join 过滤后的较小的结果集,便可以有效缩短执
行时间。而 Spark SQL 的查询优化器正是这样做的。简而言之,逻辑查询计划优化就是一个利用
基于关系代数的等价变换,将高成本的操作替换为低成本操作的过程。
1.4 什么是 DataSet
1)是 Dataframe API 的一个扩展,是 Spark 最新的数据抽象。
2)用户友好的 API 风格,既具有类型安全检查也具有 Dataframe 的查询优化特性。
3)Dataset 支持编解码器,当需要访问非堆上的数据时可以避免反序列化整个对象,提高了
效率。
4)样例类被用来在 Dataset 中定义数据的结构信息,样例类中每个属性的名称直接映射到
DataSet 中的字段名称。
5)Dataframe 是 Dataset 的特列,DataFrame=Dataset[Row] ,所以可以通过 as 方法将 Dataframe
转换为 Dataset。Row 是一个类型,跟 Car、Person 这些的类型一样,所有的表结构信息我都用 Row
来表示。
6)DataSet 是强类型的。比如可以有 Dataset[Car],Dataset[Person].
7)DataFrame 只是知道字段,但是不知道字段的类型,所以在执行这些操作的时候是没办法
在编译的时候检查是否类型失败的,比如你可以对一个 String 进行减法操作,在执行的时候才报
错,而 DataSet 不仅仅知道字段,而且知道字段类型,所以有更严格的错误检查。就跟 JSON 对
象和类对象之间的类比。
1.5 RDD、DataFrame、DataSet
相同点:
都是分布式弹性数据集
三者都有惰性机制
都有partition的概念
有许多共同的函数