赞
踩
Spark SQL是Spark用于结构化数据(structured data)处理的Spark模块。
SparkSQL
的前身是Shark
,给熟悉RDBMS
但又不理解MapReduce
的技术人员提供快速上手的工具。
Hive
是早期唯一运行在Hadoop
上的SQL-on-Hadoop
工具。但是MapReduce
计算过程中大量的中间磁盘落地过程消耗了大量的I/O
,降低的运行效率,为了提高SQL-on-Hadoop
的效率,大量的SQL-on-Hadoop
工具开始产生,其中表现较为突出的是:
Drill
Impala
Shark
其中Shark
是伯克利实验室Spark
生态环境的组件之一,是基于Hive
所开发的工具,它修改了下图所示的右下角的内存管理、物理计划、执行三个模块,并使之能运行在Spark
引擎上。
Shark
的出现,使得SQL-on-Hadoop
的性能比Hive
有了10-100倍的提高。
但是,随着Spark
的发展,对于野心勃勃的Spark
团队来说,Shark
对于Hive
的太多依赖(如采用Hive
的语法解析器、查询优化器等等),制约了Spark
的One Stack Rule Them All
的既定方针,制约了Spark
各个组件的相互集成,所以提出了SparkSQL
项目。SparkSQL
抛弃原有Shark
的代码,汲取了Shark
的一些优点,如内存列存储(In-Memory Columnar Storage
)、Hive
兼容性等,重新开发了SparkSQL
代码;由于摆脱了对Hive
的依赖性,SparkSQL
无论在数据兼容、性能优化、组件扩展方面都得到了极大的方便:
SparkSQL
不但兼容Hive
,还可以从RDD
、parquet
文件、JSON
文件中获取数据,未来版本甚至支持获取RDBMS
数据以及cassandra
等NOSQL
数据;In-Memory Columnar Storage
、byte-code generation
等优化技术外、将会引进Cost Model
对查询进行动态评估、获取最佳物理计划等等;SQL
的语法解析器、分析器还是优化器都可以重新定义,进行扩展。
2014年6月1日Shark
项目和SparkSQL
项目的主持人Reynold Xin
宣布:停止对Shark
的开发,团队将所有资源放SparkSQL
项目上,至此,Shark
的发展画上了句话,但也因此发展出两个支线:SparkSQL
和Hive on Spark
。
其中SparkSQL
作为Spark
生态的一员继续发展,而不再受限于Hive
,只是兼容Hive
;而Hive on Spark
是一个Hive
的发展计划,该计划将Spark
作为Hive
的底层引擎之一,也就是说,Hive
将不再受限于一个引擎,可以采用Map-Reduce
、Tez
、Spark
等引擎。
对于开发人员来讲,SparkSQL
可以简化RDD
的开发,提高开发效率,且执行效率非常快,所以实际工作中,基本上采用的就是SparkSQL
。SparkSQL
为了简化RDD
的开发,提高开发效率,提供了2个编程抽象,类似SparkCore
中的RDD
:
DataFrame
DataSet
① 易整合
无缝的整合了SQL
查询和Spark
编程
② 统一的数据访问
使用相同的方式连接不同的数据源
③ 兼容 Hive
在已有的仓库上直接运行SQL
或者HiveQL
④ 标准数据连接
通过JDBC
或者ODBC
来连接
在Spark
中,DataFrame
是一种以RDD
为基础的分布式数据集,类似于传统数据库中的二维表格。
DataFrame
与RDD
的主要区别在于,前者带有schema
元信息,即DataFrame
所表示的二维表数据集的每一列都带有名称和类型。这使得Spark SQL
得以洞察更多的结构信息,从而对藏于DataFrame
背后的数据源以及作用于DataFrame
之上的变换进行了针对性的优化,最终达到大幅提升运行时效率的目标。反观RDD
,由于无从得知所存数据元素的具体内部结构,Spark Core
只能在stage
层面进行简单、通用的流水线优化。
同时,与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
进行优化。比如下面一个例子:
为了说明查询优化,我们来看上图展示的人口数据分析的示例。图中构造了两个DataFrame
,将它们join
之后又做了一次filter
操作。如果原封不动地执行这个执行计划,最终的执行效率是不高的。因为join
是一个代价较大的操作,也可能会产生一个较大的数据集。如果我们能将filter下推到join
下方,先对DataFrame
进行过滤,再join
过滤后的较小的结果集,便可以有效缩短执行时间。而Spark SQL
的查询优化器正是这样做的。简而言之,逻辑查询计划优化就是一个利用基于关系代数的等价变换,将高成本的操作替换为低成本操作的过程。
DataSet
是分布式数据集合。DataSet
是Spark 1.6
中添加的一个新抽象,是DataFrame
的一个扩展。它提供了RDD
的优势(强类型,使用强大的lambda
函数的能力)以及Spark SQL
优化执行引擎的优点。DataSet
也可以使用功能性的转换(操作map
,flatMap
,filter
等等):
DataSet
是DataFrame API
的一个扩展,是SparkSQL
最新的数据抽象API
风格,既具有类型安全检查也具有DataFrame
的查询优化特性;DataSet
中定义数据的结构信息,样例类中每个属性的名称直接映射到DataSet
中的字段名称;DataSet
是强类型的。比如可以有DataSet[Car]
,DataSet[Person]
。DataFrame
是DataSet
的特列,DataFrame=DataSet[Row]
,所以可以通过as
方法将DataFrame
转换为DataSet
。Row
是一个类型,跟Car
、Person
这些的类型一样,所有的表结构信息都用Row
来表示。获取数据时需要指定顺序Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。