Spark Sql

1、SparkSql概述
1.1混乱的前世今生
先出现MapReduce,后本着sql on mr的思路,产生了Hive。
MapReduce执行效率太慢,效率升级后产生了Tez,再效率升级后产生了Spark。
Spark为了方便操作,本着sql on spark的思路产生Shark,但Shark太多的借鉴和依赖Hive,制约了Spark的One Stack Rule Them All既定方针,制约了Spark各个组件的相互集成
最后被Spark团队推翻和停更,推出了sql on spark新项目SparkSql,使sql on spark的发展方向上,得到质的提升。
1.2 SparkSql简介
SparkSql是什么
oSpark SQL是Spark处理数据的一个模块
o专门用来处理结构化数据的模块,像json,parquet,avro,csv,普通表格数据等均可。
o与基础RDD的API不同,Spark SQL中提供的接口将提供给更多关于结构化数据和计算的信息,并针对这些信息,进行额外的处理优化。
SparkSql操作方式说明
oSparkSql shell
类似于hive shell
oDataFrames API
最早专为sql on spark设计的数据抽象,与RDD相似,增加了数据结构scheme描述信息部分。
写spark代码,面向DF(DataFrams缩写)编程,可以与其它Spark应用代码无缝集成。
比RDD更丰富的算子,更有利于提升执行效率、减少数据读取、执行计划优化。
oDataSets API
集成了RDD强类型和DataFrames结构化的优点,官方正强力打造的新数据抽象类型。
写spark代码,面向DS编程,可以与其它Spark应用代码无缝集成。
比RDD更丰富的算子,更有利于提升执行效率、减少数据读取、执行计划优化。
o面向程序接口对接的操作:通过JDBC、ODBC等方式操作SparkSql
通过jdbc、odbc链接后,发送相关的sparksql请求,实现基于sparksql功能开发。
SparkSql的特点
o可以利用SQL、DataFrams API、DataSets API或其它语言调用的基于sparksql模块计算,均是sparkcore执行引擎,其对计算的表达是独立的,即开发人员可以轻松在不同API之间切换实现相同的功能。
o也可以通过命令行、JDBC、ODBC的方式来操作SparkSQL,方便其它数据平台、BI平台使用SparkSql模块。
o在spark应用程序开发中,可以无缝使用SparkSql操作数据。
o可以直接使用Hive表格数据。
o与Hive的兼容性极好:它复用了Hive的前端(去掉驱动mapreduce执行任务的部分)和元数据,因此可以拿过来hivesql的东西在sparksql上运行即可。
并不是100%完全兼容,但绝大多数情况下,不需要改动,或只需要极小的改动!!!
比如个别版本不支持直接insert into table xxx values(xxx…)的插入数据的方式
oSparkSql的应用中,sql是一个重要方面,但不局限制sql。
SparkSql愿景
o写更少的代码
o读更少的数据
o把优化的工作交由底层的优化器运行
把优化工作拿掉,我们并不需要做一些优化工作,也就是小白和高手写出来的应用程序最后的执行效率都是一样的。
1.3 Hadoop生态圈SQL相关重要名词解释
SQL
o面向数据编程的最高级抽象
HQL=Hive Sql
osql on hadoop的落地
Hive on mr
osql on mapreduce引擎
Hive on tez
osql on tez引擎
Shark
o早期发展的sql on spark项目,已废弃
SparkSql
ospark团队主推的sql on spark项目,目前已相对成熟
osql on spark商用的首选
Hive on spark
oHive团队的主推,但没有得到spark团队的强力支持。
o是sql on spark的第2选择,但相对bug和使用复杂度略高
2、SparkSql Shell操作SparkSql
环境进入方式
//直接输入spark-sql+自己想要添加的参数即可,与spark-shell相似
spark-sql [options]
//如指定运行模式
spark-sql local[*]
//如指定运行spark webui服务的端口,解决多人共用一个入口机时候的进入时候报port bind exception的问题
spark-sql --conf spark.ui.port=4075
//也可以用于似于hive -e的方式,直接直接一段sparksql代码
spark-sql –e “sparksql code”
成功进入后状态
在这里插入图片描述
操作方式
o使用方式融合几乎全部hive操作:集成了hive前端使用+元数据信息
DDL、DML、DQL
创建库
创建表
删除表
数据装载(不支持直接insert into table … values(…)方式)
更多的系统函数,包含全部的hive系统函数
添加自定义udf/udaf/udtf等
动态自定义分区
hive数据分析数
及其它hive的各项功能
3、DataFrames API操作SparkSql
3.1 开发环境搭建步骤
与之Sbt构建SparkWordCount步骤完全一样。
将Spark-Sql库依赖,加入build.sbt
osbt reload
osbt eclipse
oeclipse项目中进行刷新操作
spark-sql依赖库
“org.apache.spark” %% “spark-sql” % “1.6.2” % “provided”
3.2 DataFrames相关操作
创建DataFrames
package com.tl.job003.sql
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
object SparkSqlTest {
def main(args: Array[String]) {
val conf = new SparkConf()
conf.setMaster(“local”);
conf.setAppName(“TestSparkSql”);
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
// 添加将RDD转化为DataFrame的功能包引入
import sqlContext.implicits._
val df = sqlContext.read.json(“file:\E:\test\job003\sparksql\input_weibo.json”)
df.show();
sc.stop();
}
}
DataFrame常用操作
o常用命令
show
printSchema
select
filter
groupBy
count
orderBy
其它操作类比于sql即可
o综合示例
package com.tl.job003.sql
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
object SparkSqlTest {
def main(args: Array[String]) {
val conf = new SparkConf()
conf.setMaster(“local”);
conf.setAppName(“TestSparkSql”);
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
// 添加将RDD转化为DataFrame的功能包引入
import sqlContext.implicits._
val df = sqlContext.read.json(“file:\E:\test\job003\sparksql\input_weibo.json”)
//默认显示内容的top20
df.show()
// 打印内容对应的表结构
df.printSchema()
// 选择内容当中的某一个列对应的内容
df.select(“content”).show()
// 选择任意列并进行自定义操作
df.select(df(“content”), df(“commentCount”), df(“commentCount”) + 10000).show()
// 选择评论数大于100的数据显示出来
df.filter(df(“commentCount”) > 100).show()

// 按userId进行分组计数统计
df.groupBy(“userId”).count().show()

//分组统计结果按默认升序排列
df.groupBy(“userId”).count().orderBy(“count”).show()

//分组统计结果按降序排列
import org.apache.spark.sql.functions._
df.groupBy(“userId”).count().orderBy(desc(“count”)).show()
sc.stop();
}
}
RDD与DataFrame互操作
o将RDD转化成DataFrame(将无结构化数据转化成有结构化数据)
将一个RDD转化为带Scheme的DataFrame
实现转化的方式有两种
反射推断
程序编码实现数据与结构的对应,达到转化目标。(重点)
package com.tl.job003.sql
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType
object SparkSqlTest {
def main(args: Array[String]) {
val conf = new SparkConf()
conf.setMaster(“local”);
conf.setAppName(“TestSparkSql”);
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
// 添加将RDD转化为DataFrame的功能包引入
import sqlContext.implicits._
//将一个RDD转化成对应的DF
//首先定义scheme
val schema =
StructType(
“stdNo name classNo className”.split(" “).map(fieldName => StructField(fieldName, StringType, true)))
// 创建一个Row RDD
val studentRDD = sc.textFile(“file:\E:\test\job003\sparksql\input_rdb_student.txt”)
val rowRDD = studentRDD.map(_.split(”\t")).map(p => Row(p(0), p(1), p(2), p(3)))
// 将schema和RDD进行整合,形成df
val studentDataFrame = sqlContext.createDataFrame(rowRDD, schema)

// df输出测试
studentDataFrame.printSchema()
studentDataFrame.show()
sc.stop();
}
}
o将DataFrame转化成RDD
//提供直接转化成RDD的方式,即df.rdd即可
studentDataFrame.rdd
oSparkSql临时表生成(内存中存放的表,应用结束即消失)
直接通过df注册生成
//将df对象直接注册成一张临时表
df.registerTempTable(“weibo_doc”);
o将RDD转换成DF后,再如上例注册成临时表
o临时表与DataFrame互操作
应用开发中,使用SqlContext调用sql语句生成DataFrame
综合示例
package com.tl.job003.sql
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
object SparkSqlTest {
def main(args: Array[String]) {
val conf = new SparkConf()
conf.setMaster(“local”);
conf.setAppName(“TestSparkSql”);
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
// 添加将RDD转化为DataFrame的功能包引入
import sqlContext.implicits._
val df = sqlContext.read.json(“file:\E:\test\job003\sparksql\input_weibo.json”)
//注册为名称为weibo_doc的临时表
df.registerTempTable(“weibo_doc”);

//执行该sql,并做相应的dataframe操作即可
sqlContext.sql(“select userId,content from weibo_doc order by commentCount desc”).show();

sc.stop();
}
}
DataFrame数据持久化
oparquet数据格式,默认的输入和输出均为该格式
ospark自带:天然集成,强力推荐的数据格式
parquet产生背景
o面向分析型业务的列式存储格式
o由Twitter和Cloudera合作开发,2015年5月从Apache的孵化器里毕业成为Apache顶级项目.
oTwitter的日志结构是复杂的嵌套数据类型,需要设计一种列式存储格式,既能支持关系型数据(简单数据类型),又能支持复杂的嵌套类型的数据,同时能够适配多种数据处理框架。
parquet的优点
o压缩数据,内部自带gzip压缩
o不失真
o减少IO吞吐量
o高效的查询
o多数据处理平台,均支持parquet,包括hive等。
综合示例实现
package com.tl.job003.sql
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
object SparkSqlTest {
def main(args: Array[String]) {
val conf = new SparkConf()
conf.setMaster(“local”);
conf.setAppName(“TestSparkSql”);
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
// 添加将RDD转化为DataFrame的功能包引入
import sqlContext.implicits._
val df = sqlContext.read.json(“file:\E:\test\job003\sparksql\input_weibo.json”)
//注册为名称为weibo_doc的临时表
df.registerTempTable(“weibo_doc”)
//执行该sql,并做相应的dataframe操作即可
val resultDF = sqlContext.sql(“select userId,content from weibo_doc order by commentCount desc”)

resultDF.repartition(1).write.format(“parquet”).save(“file:\E:\test\job003\sparksql\output”);
sc.stop();
}
}
4、DataSets API操作SparkSql
1开发环境搭建步骤
o与DataFrames完全相同
2 DataSets相关操作
o操作说明
DataSet集成了RDD和DataFrame的优点,也称为强类型的DataFrame。
DataSets和DataFrames具有完全相同的成员函数。
两者中,每个行的数据类型不同。DataFrame也可以叫Dataset[Row],即DataFrame是Dataset的一种特定形式。而DataSet的每一行是不固定的,需要模式匹配来确定。
o版本说明
在1.6.2版本DataSet为alpha版测试功能,API方面均没有得到丰富和完善。
在2.0.0开始DataSet得到正式推广使用,由于其API和DataFrame在成员函数中完全对等,在使用上差异极小,由于是强类型,故仅在数据集case class模式匹配时,有明显差别。
5、多数据集抽象类型对比分析
spark抽象数据集列表
oRDD
oDataFrame
oDataSet
相同点
o全都是spark平台下的分布式弹性数据集,为处理超大型数据提供便利
o三者都有惰性机制,在进行Transform操作时不会立即执行,在遇到Action操作时会正式提交作业执行。
o均采用spark的内存运算和优化策略,内存使用和执行效率上均可以得到保障。
o均有partition的概念,便于分布式并行计算处理,达到分而治之。
o均有许多共同的函数,如map、filter、sort等。
o在进行三者的相关操作时候,个别特殊操作时必须引入一个相同的包依赖。( 早期称为 import sqlContext.implicits.,最新版本称为import spark.implicits.)
oDF和DS均可以通过模式匹配获取内部的变量类型和值。
oDF和DS产生于SparkSql,天然支持SparkSql。
区别点
oRDD
不支持SparkSql操作,均需进行转成DF或是DS才行。
类型是安全的,编译时候即可检查出类型错误。(强类型)
机器间通信、IO操作均需要序列化、反序列化对象,性能开销大。
oDataFrame
有scheme的RDD:比RDD增加了数据的描述信息。
比RDD的API更丰富,增加了针对结构化数据API。
只有一个固定类型的DataSet,即为DataFrame=DataSet[Row]
序列化和反序列化时做了结构化优化,减少了不必要的结构化信息的序列化,提高了执行效率。
oDataSet
强类型的DataFrame,与DF有完全相同的成员函数。
每行的类型不固定,需要使用模式匹配case class后,获取实际的类信息、字段类型、字段值。
访问对象数据时,比DF更加直接简单。
在序列化和反序列化时,引入了Encoder机制,达到按需序列化和反序列化,不必像之前整个对象操作了,进一步提高了效率。
应用场景
o使用RDD场景
数据为非结构化,如流媒体等数据
对数据集进行底层的转换、处理、控制
不需要列式处理,而是通过常规的对象.属性来使用数据。
对DF、DS带来的开发效率、执行效率提升不敏感时
o使用DF(必须)
R或是python语言开发者,使用DF
o使用DS(必须)
在编译时就有高度的类型安全,想要有类型的JVM对象,用上Catalyst优化,并得益于Tungsten生成的高效代码
o使用DF、DS场景
需要丰富的语义、高级抽象和特定领域专用的API时
处理需要对半结构化数据进行高级处理,如filter、map、aggregation、average、sum、SQL查询、列式访问或使用lambda函数
在不同的Spark库之间使用一致和简化的API

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值