有多种方式去使用Spark SQL:
- SQL
- DataFrames API
- Datasets API
但无论是哪种API或者是编程语言,它们都是基于同样的执行引擎,因此你可以在不同的API之间随意切换,它们各有各的特点.cuiyaonan2000@163.com
参考:
- spark结构化数据处理:Spark SQL、DataFrame和Dataset_qq_21355765的博客-CSDN博客
- 大数据基础---SparkSQL_Dataset和DataFrame简介 - 数据驱动 - 博客园
使用Spark SQL的一种方式就是通过SQL语句来执行SQL查询。当在编程语言中使用SQL时,其返回结果将被封装为一个DataFrame.
DataFrame是一个分布式集合(既然是分布式集合是否就天然的支持分布式计算,以解决大数据的情况cuiyaonan2000@163.com),是一个由具名列组成的数据集。它概念上等价于关系数据库中的表,但底层做了更多的优化。
DataFrame可以从很多数据源构建,比如:已经存在的RDD、结构化文件、外部数据库、Hive表。
DataFrame 与 RDD的区别DataFrame的前身是SchemaRDD,从Spark 1.3.0开始SchemaRDD更名为DataFrame。与SchemaRDD的主要区别是:DataFrame不再直接继承自RDD,而是自己实现了RDD的绝大多数功能。
你仍旧可以在DataFrame上调用.rdd方法将其转换为一个RDD。RDD和DataFrame的区别如下所示:
- RDD可看作是分布式的对象的集合,Spark并不知道对象的详细模式信息,
- DataFrame可看作是分布式的Row对象的集合,DataFrame 内部的有明确 Scheme 结构,即列名、列字段类型都是已知的,这带来的好处是可以减少数据读取以及更好地优化执行计划,从而保证查询效率。
- 如果你想使用函数式编程而不是 DataFrame API,则使用 RDDs;
- 如果你的数据是非结构化的 (比如流媒体或者字符流),则使用 RDDs,
- 如果你的数据是结构化的 (如 RDBMS 中的数据) 或者半结构化的 (如日志),出于性能上的考虑,应优先使用 DataFrame。
Dataset 也是分布式的数据集合,在 Spark 1.6 版本被引入,它集成了 RDD 和 DataFrame 的优点,具备强类型的特点,同时支持 Lambda 函数,但只能在 Scala 和 Java 语言中使用。
在 Spark 2.0 后,为了方便开发者,Spark 将 DataFrame 和 Dataset 的 API 融合到一起,提供了结构化的 API(Structured API),即用户可以通过一套标准的 API 就能完成对两者的操作。
实际上Dataset是包含了DataFrame的功能的,这样二者就出现了很大的冗余,故Spark 2.0将二者统一:保留Dataset API,把DataFrame表示为Dataset[Row],即Dataset的子集。
Spark在迅速的发展,从原始的RDD API,再到DataFrame API,再到Dataset的出现,速度可谓惊人,执行性能上也有了很大提升。我们在使用API时,应该优先选择DataFrame & Dataset,因为它的性能很好,
DataFrame & DataSet & RDDs 总结- RDDs 适合非结构化数据的处理,而 DataFrame & DataSet 更适合结构化数据和半结构化的处理;
- DataFrame & DataSet 可以通过统一的 Structured API 进行访问,而 RDDs 则更适合函数式编程的场景;
- 相比于 DataFrame 而言,DataSet 是强类型的 (Typed),有着更为严格的静态类型检查;
- DataSets、DataFrames、SQL 的底层都依赖了 RDDs API,并对外提供结构化的访问接口。
他们的关系与位置如下图所示:
DataFrame、DataSet 和 Spark SQL 的实际执行流程都是相同的:
- 进行 DataFrame/Dataset/SQL 编程;
- 如果是有效的代码,即代码没有编译错误,Spark 会将其转换为一个逻辑计划;
- Spark 将此逻辑计划转换为物理计划,同时进行代码优化;----这里的物理计划是否能支持移动计算,这个是关键啊,其它的都是浮云cuiyaonan2000@163.com
- Spark 然后在集群上执行这个物理计划 (基于 RDD 操作) 。
执行的第一个阶段是将用户代码转换成一个逻辑计划。
- 它首先将用户代码转换成
unresolved logical plan
(未解决的逻辑计划),之所以这个计划是未解决的,是因为尽管您的代码在语法上是正确的,但是它引用的表或列可能不存在。 - Spark 使用
analyzer
(分析器) 基于catalog
(存储的所有表和DataFrames
的信息) 进行解析。解析失败则拒绝执行,解析成功则将结果传给Catalyst
优化器 (Catalyst Optimizer
)-----这里我理解就是需要有个元数据库来检查字段,表是否正确cuiyaonan2000@163.com - 优化器是一组规则的集合,用于优化逻辑计划,通过谓词下推等方式进行优化,最终输出优化后的逻辑执行计划。 ---最后优化一下
得到优化后的逻辑计划后,Spark 就开始了物理计划过程。 它通过生成不同的物理执行策略,并通过成本模型来比较它们,从而选择一个最优的物理计划在集群上面执行的。物理规划的输出结果是一系列的 RDDs 和转换关系 (transformations)。----这里是否就是大数据运算的关键???分批的读取数据放入内存,然后在进行汇总.越来越觉得这种方式的计算,必须要基于源数据库cuiyaonan2000@163.com
在选择一个物理计划后,Spark 运行其 RDDs 代码,并在运行时执行进一步的优化,生成本地 Java 字节码,最后将运行结果返回给用户。