sparksql介绍
sparksql是spark用来处理结构化数据的一个模板,他提供了要给编程抽象叫做dataframe并且作为分布式sql查询引擎的作用
sparksql将sparksql转化为rdd,然后提交到集群执行,执行效率快
hive的应用其实是对应不会写java的开发人员,但是会写sql的数据库提供的是mr的一种简化
sparksql其实是对之前学习的sparkcore中rdd的一种简化,用sql的语言可以对rdd编程进行开发
spark是有处理上限的,10PB,超过这个范围还是要使用hive来处理的,hive的处理上限是100PB级别
sparksql优点
1.易整合
2.统一的数据访问方式
3.兼容hive
4.标准的数据连接
sparksql的操作方式
sparksql的数据抽象
对于sparkcore而言对数据的操作需要首先转换成rdd,对rdd可以使用各种算子进行处理,最终对数据进行统一操作,所以我们将rdd看做是对数据的封装(抽象)
对于sparksql而言,对数据进行操作的也需要进行转换,这里提供了两个新的抽象,分别是dataframe和dataset
RDD vs DataFrames vs DataSet
首先从版本上看
RDD
rdd是一个懒执行的不可变的可以支持functional(函数式编程)的并行数据集合.
rdd的最大好处就是简单,API的人性化程度很高
rdd的劣势是性能限制,它是一个jvm驻内存对象,这也就决定了存在gc的限制和数据增加时java序列化成本的升高
DataFrame
简单来说dataframe是rdd+schema的集合
什么是schema?
之前我们学过mysql数据库,在数据库中schema是数据库的组织和结构模式中包含了schema对象,可以是表(table)列(column)数据类型(data type),视图(view),存储过程(stored procedures),关系(relationships),主键(primary key)外键 (foreign key)等schema代表的就是一张表
与rdd类似,dataframe也是一个分布式的数据容器,然而dataframe更像传统数据库的二维表格,处理数据以外,还记录数据的结构信息,即schema,同时,与hive类似dataframe也支持嵌套数据类型(struct,array和map),从api易用性的角度上看,dataframeapi提供的是一套高层的关系操作,比函数式的rddapi更加友好,门槛更低,由于与r和pandas的dataframe类似,sparkdataframe很好的继承了传统单机数据分析的开发体验
dataframe是为数据提供了schema的视图,可以把他当做数据库中的一张表来对待,
dataframe也是懒执行的
性能比rdd要高,主要有两方面
定制化内存管理
优化执行计划
dataframe的劣势在于编译器缺少的类型安全检查,导致运行时出错,
dataframe只是知道字段但是不知道字段的类型,所以在执行这些操作的时候是没办法在编译的时候见擦汗是否类型失败的,比如你可以对一个string进行减法操作,在执行的时候才会报错,而dataset不仅仅知道字段而且世道字段类型,所以有更加严格的错误检查
dataset
是dataframeapi的一个扩展,是spark最新的数据抽象,
用户友好的api风格,既具有类型安全检查,也具有dataframe的查询优化特性,dataset支持编程解码器,当需要访问非堆上的数据式可以避免反序列化整个对象,提高了效率,
样例类被用来在dataset重定义数据的结构信息,样例类中每个属性的名称直接映射到dataset中定义的数据的结构信息,样例类中的每个属性的名称直接映射到dataset中的字段名称,
dataframe是dataset的特例,dataframe=dataset[row],所以可以通过as方法,将dataframe转换为dataset,row是一个类型,更car person这些类型一样,所有的表结构信息,我们都用row来表示
dataset是强类型,比如可以有dataset[car],dataset[person]
dataset[row]这个类似于我们学习的方形row就是泛型类型
三者的共性
1.rdd ,dataframe,dataset全都是spark平台下的分布式弹性数据库,为处理超大型数据提供便利
2.三者都有惰性机制,在进行创建,转换,如map方法时,不会立即执行,只有在遇到action如foreach是,三者才会开始遍历运算,极端情况下,如果代码里面有创建转换,,但是后面没有action中使用对应的结果,在执行时会被直接跳过
3.三者都会根据spark的内存情况自动缓存运算,这样即使数据量很大,也不用担心内存溢出
4.三者都有partition的概念
5.三者都有许多的共同函数,如filter,排序等
6.在对dataframe和dataset进行操作许多操作都需要这个包进行支持
7.dataframe和dataset均可使用模式匹配获取各个自读你的值和类型
三者的区别
rdd
rdd一般不和spark mlib同时使用
rdd不支持sparksql操作
dataframe
与rdd和dataset不同,dataframe每一行的类型固定为row,只有通过解析才能获取各个字段的值,每一列的值没法直接访问
dataframe与dataset一般不与spark mlib同时使用
dataframe与dataset均支持sparkslql的操作,比如select ,groupby之类,还能注册临时表/视窗,进行sql语句操作
dataframe与dateset支持一些特别翻遍的保存方式,比如保存成csv,可以带上表头,这样每一列的字段名一目了然
利用这样的保存方式,可以方便的获取字段名和列的对应,而且分隔符(delimiter)可以自由指定
dataset
dataset和dataframe拥有完全相同的成员函数,区别只是每一样的数据类型不同,
dataframe也可以叫dataset[row]每一行的类型是row,不解析,每一行究竟有哪些字段,各个字段优势什么类型都无从得知,只能用上面提到的getAS方法或者童星汇总的七条提出到的模式匹配拿出特定字段
而dataset中每一行是什么类型是不一定的,在自定义了case class之后可以很自由的获得每一行的信息
dataset在需要访问列中的某个字段时是非常方便的,然而,如果要写一些适配性很强的函数时,如果使用dataset,行的类型又不确定,可能是各种case class,无法实现适配,这时候用dataframe即dataset[row]就能比较好的解决问题
sparksql应用操作
在老版本中,saprksql提供了两种sql查询的起始点,一个叫sqlcontext,用于spark自己提供的sql查询,一个叫hivecontext,用于连接hive 的查询,sparksession提供 的是spark新的sql查询起始点,实际上是sqlContext和hivecontext的组合,所以在sqlcontext和hivecontext上可以用的api在sparksession上同样是可以使用的,sparksession内部封装了sparkcontext,所以计算实际上是由sparkcontext完成的
spark-shell基本操作
spark.read.json("/opt/software/spark-2.2.0-bin-hadoop2.7/examples/src/main/resources/people.json") df.show() df.filter($"age">21).show df.createOrReplaceTempView("person") spark.sql("select * from persons").show() spark.sql("select * from persons where age > 21).show()
idea编写sparksql
maven pom
<dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-sql_2.11</artifactId> <version>${spark.version}</version> </dependency>
sparksession的三种创建方式
import org.apache.spark.{SparkConf, SparkContext} import org.apache.spark.sql.{DataFrame, SparkSession} /** * SparkSession三种创建方式 */ object SparkSQLDemo { def main(args: Array[String]): Unit = { /** * 创建SparkSession方式1 * builder用于创建一个SparkSession。 * appName设置App的名字 * mast