SparkSQL

举报
bigdata张凯翔 发表于 2021/03/25 23:52:09 2021/03/25
【摘要】 Spark sql 的属性 ① 易整合: 可以通过sql开发对应的应用程序, 也可以使用java/scala/phython/R编写的API来开发 ② 统一的数据源访问: 可以使用相同的方式来连接到不同的数据源 // 即: sparkSession.read.文件格式(文件路径) ③ 兼容hive: 可以使用spark sql来操作hive sql ④ 标准的数据连接: sp...
Spark sql 的属性

① 易整合: 可以通过sql开发对应的应用程序, 也可以使用java/scala/phython/R编写的API来开发
② 统一的数据源访问: 可以使用相同的方式来连接到不同的数据源
// 即: sparkSession.read.文件格式(文件路径)
③ 兼容hive: 可以使用spark sql来操作hive sql
④ 标准的数据连接: spark sql可以使用标准的数据库连接(JDBC, ODBC)来操作关系型数据库

1) DataFrame与RDD的优缺点

image.png

DataFrame通过引入schema (即数据的结构信息)和off-heap(不在堆里面的内存,指的是除了不在堆的内存,使用操作系统上的内存),解决了RDD的缺点, Spark通过schame就能够读懂数据, 因此在通信和IO时就只需要序列化和反序列化数据, 而结构的部分就可以省略了;通过off-heap引入,可以快速的操作数据,避免大量的GC。但是却丢了RDD的优点,DataFrame不是类型安全的, API也不是面向对象风格的

2)读取数据源创建DataFrame

① 读取文本文件创建DataFrame
sparkSession.read.text(“路径 + txt文件名”)
② 读取json文件创建DataFrame
sparkSession.read.json(“路径 + json文件名”)
③ 读取parquet列式存储格式文件创建DataFrame
sparkSession.read.parquet(“路径 + parquet文件名”)

3)DataFrame、DataSet、RDD的区别


image.png

DataSet包含了DataFrame的功能,Spark2.0中两者统一,DataFrame表示为DataSet[Row],即DataSet的子集
① DataSet可以在编译时检查类型 (即类型安全)
② 并且是面向对象的编程接口
// 也就是说, DataSet弥补了DataFrame的缺点, 并且继承了它的优点

SparkSQL中join操作与left join操作的区别?

join和sql中的inner join操作很相似,返回结果是前面一个集合和后面一个集合中匹配成功的,过滤掉关联不上的。
leftJoin类似于SQL中的左外关联left outer join,返回结果以第一个RDD为主,关联不上的记录为空。
部分场景下可以使用left semi join替代left join:
因为 left semi join 是 in(keySet) 的关系,遇到右表重复记录,左表会跳过,性能更高,而 left join 则会一直遍历。但是left semi join 中最后 select 的结果中只许出现左表中的列名,因为右表只有 join key 参与关联计算了
① 通过反射推断Schema

// 这种方式首先是定义样例类Person, 然后通过将rdd与该样例类关联(通过样例类创建schema,case class的参数名称会被利用反射机制作为列名) 生成最终的RDD, 最后该RDD调用toDF方法转换为DataFrame. 有了DataFrame之后就可以调用各种方法来执行spark sql查询了

case class Person(id:Int,name:String,age:Int)
//读取数据文件
sc.textFile("d:\\person.txt").map(x=>x.split(" "))
//5.将rdd转换成dataFrame
//手动导入隐式转换
import spark.implicits._
val personDF:DataFrame=personRDD.toDF

这种方式首先是定义样例类Person, 然后通过将rdd与该样例类关联(通过样例类创建schema,case class的参数名称会被利用反射机制作为列名) 生成最终的RDD, 最后该RDD调用toDF方法转换为DataFrame. 有了DataFrame之后就可以调用各种方法来执行spark sql查询了
② 通过StructType直接指定Schema

//4.将rdd与Row类型关联
data.map(x=>Row(x(0).toInt,x(1),x(2).toInt))
//5.通过StructType指定schema
val schema:StructType=StructType( structField("id",IntegerType,true) :: structField("name",IntegerType,false) :: structField("age",IntegerType,false) ::Nil)\
//6.sparkSession的createDataFrame  获取dataFrame
val df:DataFrame=spark.createDataFrame(rowRDD,schema)

2)编写Spark SQL程序操作HiveContext

val spark:SparkSession=SparkSession.builder() .appName("HiveSupport") .master("local[2]") .enableHiveSupport() .getOrCreate()

// 设置为enableHiveSupport的sparkSession可以直接操作hql (即sparkSession调用sql方法, 里面可以直接写hql语句来操作)

JDBC数据源
1)SparkSql从MySQL中加载数据

image.png

2)SparkSql将数据写入到MySQL中
image.png




简述SparkSQL中RDD、DataFrame、DataSet三者的区别与联系? (笔试重点)

1)RDD
优点:
编译时类型安全
编译时就能检查出类型错误
面向对象的编程风格
直接通过类名点的方式来操作数据
缺点:
序列化和反序列化的性能开销
无论是集群间的通信, 还是IO操作都需要对对象的结构和数据进行序列化和反序列化。
GC的性能开销 ,频繁的创建和销毁对象, 势必会增加GC
2)DataFrame
DataFrame引入了schema和off-heap
schema : RDD每一行的数据, 结构都是一样的,这个结构就存储在schema中。 Spark通过schema就能够读懂数据, 因此在通信和IO时就只需要序列化和反序列化数据, 而结构的部分就可以省略了。
3)DataSet
DataSet结合了RDD和DataFrame的优点,并带来的一个新的概念Encoder。
当序列化数据时,Encoder产生字节码与off-heap进行交互,能够达到按需访问数据的效果,而不用反序列化整个对象。Spark还没有提供自定义Encoder的API,但是未来会加入。
三者之间的转换:


image.png

Join常见分类以及基本实现机制[面试题]

当前SparkSQL支持三种Join算法-shuffle hash join、broadcast hash join以及sort merge join。其中前两者归根到底都属于hash join,只不过在hash join之前需要先shuffle还是先broadcast
SparkSQL – 有必要坐下来聊聊Join

文章来源: www.jianshu.com,作者:百忍成金的虚竹,版权归原作者所有,如需转载,请联系作者。

原文链接:www.jianshu.com/p/ce492c0dada7

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。