Spark指南——第三章:SparkSQL概述(1)

tech2022-12-15  105

SparkSQL概述(1)

一、SparkSQL概述二、DataFrame三、Dataset:类型安全的结构化API四、DataFrame与 Dataset的比较五、where to go

一、SparkSQL概述

我们知道Hive,它是将Hive SQL转换成MapReduce然后提交到集群上执行,大大简化了编写MapReduc的程序的复杂性,但是由于Hive基于MapReduce进行处理,在该过程中大量的中间磁盘落地过程消耗了大量的I/O,这大大降低了运行效率。所有Spark SQL的应运而生,它是将Spark SQL转换成RDD,然后提交到集群执行,执行效率非常快!

Spark的RDD API 比传统的MapReduce API在易用性有了巨大的提升,但是对于没有MapReduce和函数式编程经验的新手,RDD API还是存在一定的门槛。Spark在SchemaRDD的基础上,提供了2个编程抽象:DataFrame和DataSet,作为分布式SQL查询引擎的作用。仅大大降低了新手学习门槛高,最重要的是脱胎SchemaRDD的DataFrame/DataSet支持分布式大数据处理。

SparkSQL对SQL语句的处理和关系型数据库采用了类似的方法,SparkSQL先会将SQL语句进行解析(Parse) 形成一个Tree,然后使用Rule 对Tree进行绑定、优化等处理过程,通过模式匹配对不同类型的节点采用不同的操作。而Spark SQL的查询优化器是Catalyst,它负责处理查询语句的解析、绑定、优化和生成物理计划等过程,Catalyst是SparkSQL最核心的部分,其性能优劣将决定整体的性能。

二、DataFrame

DataFrame是最常见的结构化API,DataFrame是一种以RDD为基础的分布式数据集,类似于传统数据库中的二维表格。与RDD的主要区别在于:DataFrame带有Schema元数据,即DataFrame所表示的二维表据集的每一列都带有名称和类型,简单来说它是包含行和列的数据表。说明这些列和列类型的一些规则被称为模式(schema)。 上图直观地体现了DataFrame和RDD的区别。左侧的RDD[Person]虽然以Person为类型参数,但Spark框架本身不了解Person类的内部结构。而右侧的DataFrame却提供了详细的结构信息,使得Spark SQL可以清楚地知道该数据集中包含哪些列,每列的名称和类型各是什么。DataFrame是为数据提供了Schema的视图。可以把它当做数据库中的一张表来对待。

三、Dataset:类型安全的结构化API

Dataset 是 Dataframe API的一个扩展,是Spark最新的数据抽象。Dataset是类型安全的结构化API,用于在Java和Scala中编写静态类型的代码。Dataset API在Python和R中不可用,因为这些语言是动态类型的。Dataframe是Dataset的特列,DataFrame=Dataset[Row] ,所以可以通过as方法将Dataframe转换为Dataset。Row是一个类型,跟Car、Person这些的类型一样,所有的表结构信息我都用Row来表示。DataSet是强类型的。比如可以有 Dataset[Car],Dataset[Person].DataFrame只是知道字段,但是不知道字段的类型,所以在执行这些操作的时候是没办法在编译的时候检查是否类型失败的,比如你可以对一个String进行减法操作,在执行的时候才报错,而DataSet不仅仅知道字段,而且知道字段类型,所以有更严格的错误检查。就跟JSON对象和类对象之间的类比。通常样例类被用来在Dataset中定义数据的结构信息,样例类中每个属性的名称直接映射到DataSet中的字段名称。

四、DataFrame与 Dataset的比较

实质上,结构化API包含两类API,即非类型化的DataFrame和类型化的Dataset。说DataFrame是无类型的可能不太准确,因为它们其实是有类型的,只是Spark完全负责维护它们的类型,仅在运行时检查这些类型是否与schema中指定的类型一致。与之相对应的,Dataset在编译时就会检查类型是否符合规范。Dataset仅适用于基于Java虚拟机(JVM)的语言(比如Scala和Java),并通过case类或Java beans指定类型。

因此在大多数情况下,你会使用DataFrame。在Scala版本的Spark中, DataFrame就是一些Row类型的Dataset的集合。“Row”类型是Spark用于支持内存计算而优化的数据格式。这种格式有利于高效计算,因为它避免使用会带来昂贵垃圾回收开销和对象实例化开销的JVM类型,而是基于自己的内部格式运行,所以并不会产生这种开销。Python版本和R语言版本的Spark并不支持Dataset,所有东西都是DataFrame,这样我们就可以使用这种优化的数据格式进行计算处理。

五、where to go

第三章:SparkSQL编程(2)

最新回复(0)