1、SparkSQL基础理论
1.1、RDD、DataFrame、Dataset区别
(1)RDD
弹性分布式数据集,Spark中最基础的数据抽象,特点是RDD只包含数据本身,没有数据结构。
- 样例
(2)DataFrame
1、分布式数据集,可以理解为一张分布式表或视图
2、包含Schema信息(数据的结构信息,列名,列数据类型)
3、丰富的sql算子
4、弱类型,不支持编译期检查
- 样例
(3)DataSet
1、可以像DataFrame一样调用sql算子
2、强类型,可支持编译期检查
- 样例
1.2、Row和Schema的区别
Sparksql允许Spark执行用SQL,hiveQL或者Scala表示的关系查询,模块核心是一个新类型的RDD-SchemaRDD
SchemaRDDs
组成对象:由行对象组成,行对象拥有一个模式(schema)来描述行中每一列的数据类型
创建方式:可以通过存在的RDD、一个parquet文件、一个JSON数据库或存储在Hive中的数据执行HiveSQL查询中创建
- Row:一个泛化的无类型JVM object
val row1 = Row(1,'abc',1.2)
- Schema:是每列的名称和数据类型,通过Schema可以知道数据集中包含那些列及列的数据类型
val schema:StructType = StructType(
Array(
StructField("user_id",IntegerType,true),
StructField("item_id",IntegerType,true),
StructField("rating",DoubleType,true),
StructField("timestamp",LongType,true)
)
)
2、SparkSQL基本操作
- 项目开发:采用DSL+SQL混写写法书写SparkSQL
1、普通转换和聚合算子:使用DSL风格书写
2、窗口函数:使用SQL风格书写
2.1、初始化SparkContext
- SparkContext使用Py4J启动JVM并创建JavaSparkContext。
sc = SparkContext(appName=key_cal + "_sql_daily")
hsqlContext = HiveContext(sc)
#HiveContext是通往hive入口。
#HiveContext具有SQLContext的所有功能。
2.2、读取数据
- 通过Spark的API中 - hsqlContest.sql进行相关操作
midsqlDf = hsqlContext.sql("select "
"idcard,"
"datediff('{current_time}', first_value(repay_tm) over(partition by no_mec,idcard order by repay_tm)) as day_open"
"from {mid_table}".format(current_time=self.yes_time, mid_table=input_mid_table_name))
2.3、注册临时表
- registerDataFrameAsTable将其注册为临时表
hsqlContext.registerDataFrameAsTable(midsqlDf, "personal_cfsl_loan_deduct_seq_mid")
2.4、写入数据
- hsqlContext.sql(sql):运行sql将数据写入
sql = """
insert overwrite table zj_var.zj_var_w2 partition(dt='{yes_time}')
select
tforth.idcard as idcard
from
zj_var.zj_var_mid_forth_1 tforth
""".format(yes_time=v_dt)
hsqlContext.sql(sql)
2.5、关闭Spark
sc.stop()
3、SparkSQL执行流程
1、提交SQL,解析器(sqlparser)将SQL文本解析成逻辑计划;
2、分析器结合Catalog(存储了表信息)对逻辑计划做进一步分析,验证表是否存在,操作是否支持;
3、优化器对分析器分析的逻辑计划做进一步的优化,如将过滤逻辑推到子查询,子查询公用等;
4、planner再将优化后的逻辑计划根据预设的映射逻辑转换为物理执行计划;
5、物理执行计划做RDD计算,最终向用户返回查询数据
4、SparkSQL的Join原理
4.1、Join实现方式
- SparkSQL有三种Join的实现,每种Join对应的不同的应用场景
Broadcast Hash Join:适合一张很小的表合一张大表进行join
Shuffle hash join:适合一张小表(比上面大一点)合一张达标进行Join
Sort Merge Join:适合两张达标进行Join
注意:前两者都是基于Hash Join,只不过Hash Join之前需要先shuffle还是先brocadcast
- 注意:SparkSQL自动决策使用哪种实现方式
4.2、Hash Join
Hash Join:小表被作为驱动表加载到内存中,大表作为探测表,逐行遍历
注意:hash join是传统数据库中的单机join算法,分布式环境下改造成两种方案
:Ⅰ、Broadcast Hash Join
:Ⅱ、Shuffle hash join
4.3、Broadcast Hash Join
- 使用场景:适合小表很小,可以直接广播的场景
实现步骤:
1、Broadcast阶段:小表广播分发到所有主机,广播算法很多种
2、hash join阶段:每个executor上执行hash join,小表映射,大表试探
4.4、shuffle hash join
- 使用场景:小表数据量稍大的情况
实现步骤:分而治之
1、shuffle阶段:分别将两个表按照join key进行分区,将相同的key的记录分布于同一节点,两张表的数据会被重新分布到集群中
2、hash join阶段:每个分区节点上的数据单独执行hash join算法(小表映射,大表试探)
实现原理:根据join key相同分区必然相同的原理,将两张表分别按照join key进行重新组织分区
4.5、Sort Merge Join阶段
- 使用场景:两张表都非常大的时候
实现步骤:
1、shuffle阶段:将两张大表根据join key 进行重新分区,两张表数据会分布到整个集群
2、sort阶段:对单个节点的量表数据,分别及逆行排序;
3、merge阶段:对排好序的两张分区表数据执行join操作。
***join操作:分别遍历两个有序序列,碰到相同join key就merge输出
4.6、深究问题(待补充)
sort-merge join的代价并不比shuffle hash join小,反而是多了很多,为什么SparkSQL还会在两张大表的场景下使用sort-merge join算法呢?
5、Spark和Hive区别
5.1、转换本质
SparkSQL:SQL语句转化为一系列的RDD转换与落地过程
Hive SQL:将SQL语句转换为多个MR job顺序运行
5.2、切分粒度
SparkSQL:是一系列细粒度的算子转换流程,可方便地对各个部分进行细致优化和自由组合
Hive SQL:只能按map和reduce的粒度进行切分,无法对其中的更细粒度,input,sort,shuffle等进行自由组合
5.3、中间结果
SparkSQL:不会将RDD转换结果在主动落磁盘,因此再多个RDD之间变换时不需要重新进行IO
Hive SQL:在多个job之间必须不断重新IO过程
5.4、Spark SQL中的Hive SQL
1、SparkSQL包含了Spark On Hive,sql语句中操作的是Hive表
2、Spark SQL默认操作的表是内存池中的虚拟表,使用完毕后,就会在内存中释放
5.5、SparkSQL和HiveSQL的窗口函数区别
- Hiveql的窗口函数:可以统计group聚合后的数据,即having后的数据
原因:hive的窗口函数发生在having之后
select id
,time
,row_number()over(partition by time order by total desc) as rank
from table
having rank <= 3
注意:在HiveSQL中不能运行,以上脚本会提示having字段错误
- SparkSQL的窗口函数:只能使用聚合前的数据,即hive前的数据
原因:Spark没有job之间的先后关系
select * from (
select id,time,date,row_number()over(
partition by time
order by count(1) desc) as rank
from table_name
group by id,time
) t
where rank <= 3
注意:以上在Spark中不可运行,会提示count(1)不属于可用字段
6、Spark On Hive 和Hive On Spark
- 相同
计算引擎:都是Spark
运行速度:相差不大
使用场合:都是实时性要求比较高的业务场景
- 区别
1、SQL语句解析引擎不同
Spark on hive:Spark解析器
hive on spark:hive解析器
2、技术面向受众不同
Spark on hive:面向Spark程序员
特点:需要编写Spark程序,在代码中嵌入sql语句,操作hive表
Hive on Spark:面向数仓程序员
特点:之前的数仓项目不用作任何变更,只需要将hive底层的计算引擎从mr切换到Spark即可