一、SparkSQL的发展
1.1 概述
SparkSQL是Spark⽣态体系中的构建在SparkCore基础之上的⼀个基于SQL的计算模块。 SparkSQL的前身不叫SparkSQL,⽽叫Shark,最开始的时候底层代码优化,sql的解析、执⾏引擎等等完全基于 Hive,总是Shark的执⾏速度要⽐hive⾼出⼀个数量级,但是hive的发展制约了Shark,所以在15年中旬的时候, shark负责⼈,将shark项⽬结束掉,重新独⽴出来的⼀个项⽬,就是sparksql,不再依赖hive,做了独⽴的发展, 逐渐的形成两条互相独⽴的业务:SparkSQL和Hive-On-Spark。在SparkSQL发展过程中,同时也吸收了Shark的一些特点:基于内存的列存储,动态字节码优化技术。
1.2 特点
官网的原话:**Spark SQL is Apache Spark’s module for working with structured data. **
即Spark SQL是Apache Spark处理结构化数据的模块。
- 集成
无缝地将SQL查询与Spark程序混合。
Spark SQL允许您使用SQL或熟悉的DataFrame API在Spark程序中查询结构化数据。适用于Java、Scala、Python和R语言。
- 统一的数据访问
以相同的方式连接到任何数据源。
DataFrames和SQL提供了一种访问各种数据源的通用方法,包括Hive、Avro、Parquet、ORC、JSON和JDBC。您甚至可以通过这些源连接数据。
- 蜂巢集成
在现有仓库上运行SQL或HiveQL查询。
Spark SQL支持HiveQL语法以及Hive SerDes和udf,允许您访问现有的Hive仓库。
- 标准的连接
通过JDBC或ODBC连接。
服务器模式为业务智能工具提供了行业标准JDBC和ODBC连接。
1.3 总结
SparkSQL就是Spark生态体系中用于处理结构化数据的⼀个模块。结构化数据是什么?存储在关系型数据库中的数据,就是结构化数据;半结构化数据是什么?类似xml、json等的格式的数据被称之为半结构化数据;非结构化数据是什么?音频、视频、图片等为非结构化数据。 换句话说,SparkSQL处理的就是⼆维表数据。
二、SparkSQL的编程入口和模型
2.1 SparkSQL编程入口
SparkSQL中的编程模型,不再是SparkContext,但是创建需要依赖SparkContext。SparkSQL中的编程模型,在spark2.0以前的版本为SQLContext和HiveContext,HiveContext是SQLContext的一个子类,提供Hive中特有的一些功能,比如row_number开窗函数等等,这是SQLContext所不具备的,Spark2.0之后将这两个模型进行了合并——SparkSession。SparkSession的构建需要依赖SparkConf或者SparkContext。使用工厂构建器 (Builder方式)模式创建SparkSession。
import org.apache.spark.sql.SparkSession;
SparkSession spark = SparkSession
.builder()
.appName("Java Spark SQL basic example")
.config("spark.some.config.option", "some-value")
.getOrCreate();
2.2 编程模型简介
主要通过两种方式操作SparkSQL,一种就是SQL,另一种为DataFrame和Dataset。
- SQL
SQL不用多说,就和Hive操作⼀样,但需要清楚一点,SQL操作的是表,所以如果用SQL进行操作,就需要将SparkSQL对应的编程模型转化成为一张表。
- DataFrame和Dataset
DataFrame和Dataset是SparkSQL中的编程模型。DataFrame和Dataset我们都可以理解为是一张mysql中的二维表,表有什么?表头,表名,字段,字段类型。RDD其实说⽩了也是一张二维表,但是这张二维表相比较于DataFrame和Dataset却少了很多东⻄,⽐如表头,表名,字段,字段类型,只有数据。 Dataset是在spark1.6.2开始出现出现的api,DataFrame是1.3的时候出现的,早期的时候DataFrame叫 SchemaRDD,SchemaRDD和SparkCore中的RDD相比较,就多了Schema,所谓约束信息,元数据信息。 ⼀般的,将RDD称之为Spark体系中的第⼀代编程模型;DataFrame⽐RDD多了⼀个Schema元数据信息, 被称之为Spark体系中的第二代编程模型;Dataset吸收了RDD的优点(强类型推断和强⼤的函数式编程)和 DataFrame中的优化(SQL优化引擎,内存列存储),成为Spark的最新⼀代的编程模型。
2.3 RDD V.S. DataFrame V.S. Dataset
创建DataFrame
1.spark.read.format("xxx")
# 这种方式对应与文件/外部输入 例如csv对应了CSVFileFormat
2.spark.createDataFrame(RDD[A])
[A<:Product] : 元组和样例类都是Product子类型
3.import spark.implicits._ // 导入sparkSession中的隐式转换操作
Seq(("a",1),("b",2),("c",3)).toDF("k","v").show()
Dataset的创建注意事项:
# 不建议使用普通类
class User(val id:Int,val name:String)
val list3 = List(new User(100,"xx"))
spark.createDataset(list3).show // list3中的类型应该存在Encoder
# 对于普通类型,要么转成样例类,否则需要手动提供Encoder隐式值
implicit val e:Encoder[User] = Encoders.javaSerialization(classOf[User])
class User(val id:Int,val name:String) extends Serializable
2.4 RDD、DataFrame、Dataset之间的转换
- RDD=>DataFrame rdd.toDF
- RDD=>Dataset rdd.toDS
- DataFrame=>RDD df.rdd
- DataFrame=>Dataset df.as[User]
- Dataset=>RDD ds.rdd
- Dataset=>DataFrame ds.toDF
2.5 DataFrame & Dataset API
网址:http://spark.apache.org/docs/2.2.0/api/scala/index.html#org.apache.spark.sql.Dataset
分类:
- Action算子:collect show
- Typed transformations 强类型转换 返回Dataset[U]
- Untyped transformations 返回DataFrame \Column
- 其它
三、SparkSQL的数据加载和落地
3.1 数据的加载
SparkSQL中加载外部