spark-sql

本文深入探讨SparkSQL的特点及性能优化技术,包括内存列存储、字节码生成等,解析SparkSQL工作原理,从SQL解析到物理计划生成全过程,提供详实的SparkSQL使用指南,涵盖RDD转换为DataFrame、UDF与UDAF自定义函数应用,以及HiveonSpark配置与最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

==>Spark-SQL前世今生

1、Spark SQL的特点
1)、支持多种数据源:Hive、RDD、Parquet、JSON、JDBC等。
2)、多种性能优化技术:in-memory columnar storage、byte-code generation、cost model动态评估等。
3)、组件扩展性:对于SQL的语法解析器、分析器以及优化器,用户都可以自己重新开发,并且动态扩展

2、Spark SQL的性能优化技术简介
1)、内存列存储(in-memory columnar storage)
2)、字节码生成技术(byte-code generation)
3)、Scala代码编写的优化

3、Spark SQL and DataFrame
Spark SQL是Spark中的一个模块,主要用于进行结构化数据的处理。它提供的最核心的编程抽象,就是DataFrame。同时Spark SQL还可以作为分布式的SQL查询引擎。Spark SQL最重要的功能之一,就是从Hive中查询数据。

DataFrame,可以理解为是,以列的形式组织的,分布式的数据集合。它其实和关系型数据库中的表非常类似,但是底层做了很多的优化。DataFrame可以通过很多来源进行构建,包括:结构化的数据文件,Hive中的表,外部的关系型数据库,以及RDD。

==>Spark-sql的使用

1、RDD转换为DataFrame(两种)
1)、使用反射的方式来推断包含了特定数据类型的RDD的元数据
2)、通过编程接口来创建DataFrame

2、UDF自定义函数和UDAF自定义聚合函数
UDF,其实更多的是针对单行输入,返回一个输出
UDAF,则可以针对多行输入,进行聚合计算,返回一个输出,功能更加强大

3、Spark-SQL工作原理
SqlParse ---------> 解析器

Analyser ---------> 分析器

Optimizer ---------> 优化器

SparkPlan ---------> 物理计划

如何把一个sql语句变成RDD

流程:

1)、自己编写的SQL语句
大家要知道,只要在数据库类型的技术里面,比如:最传统的MySQL,Oracle等,包括现在大数据领域的数据仓库,比如hive,他的基本的SQL执行的模型,都是类似的,首先都要生成一条SQL语句的执行计划

2)、通过SqlParser(解析器)生成未解析的逻辑计划(unresolved LogicalPlan)
3)、通过Analyzer(分析器)生成解析后的逻辑计划(resolved LogicalPlan)
4)、通过Optimizer(优化器)生成优化后的逻辑计划(optimized LogicalPlan)
实际上,比如传统的Oracle等数据库,通常都会生成多个执行计划,然后呢,最后有一个优化器,针对多个计划,选择一个最好的计划,而SparkSql这儿的优化指的是,比如说,刚生成的执行计划中,有些地方的性能是显而易见的,不太好,举例说明:
比如说,我们有一个SQL语句,select name from (select … from …) where …=…;
此时,在执行计划解析出来的时候,其实就是按照他原封不动的样子,来解析成可以执行的计划,但是呢,Optimizer 在这里其实就会对执行计划进行优化,比如说,发现where 条件,其实可以放在子查询中,这样,子查询的数量大大变小,可以优化执行速度,此时,可能就会变成如下这样:select name from (select name from …where …=…)

5)、通过SparkPlan,生成最后的物理计划(PhysicalPlan)
到物理计划这里,那么其实就是非常“接地气”的计划了。就是说,已经很明朗了,从那几个文件读取什么数据,从那几个文件中读取,如何进行关联等等

6)、在executor中执行物理计划
逻辑的执行计划,更多的是偏向于逻辑,比如说吧,大致就是这种样子的,
From table students=>filter … => select name …
这里基本上,逻辑计划都是采用Tree ,树形结构

7)、生成RDD
Select name from students => 解析,从哪里去查询,students表,在哪个文件里,从哪个文件中查询哪些数据,比如说是name这个列,此外,复杂的SQL,还有,比如说查询时,是否对表中的数据进行过滤和筛选,更不用说,复杂时,需要有多表的JOIN(咋传统数据库中,比如MySQL,执行计划还涉及到如何扫描和利用索引)

4、spark-SQL性能优化

1)、设置shuffle过程的并行度:(SQLContext.setConf())
spark.sql.shuffle.partitions
2)、在hive数据仓库建设过程中,合理设置数据类型,比如能设置为int的,就不要设置为bigInt,减少数据类型导致不必要的内存开销

3)、编写SQL时,尽量给出明确的列名,比如select name from students。不要写select * 的方式。

4)、并行处理查询结果:对于spark-SQL查询的结果,如果数据量比较大,比如超过1000条,那么就不要一次性的collect()到driver再处理,使用foreach()算子,并行处理查询结果
5)、缓存表:对于一条SQL语句可能对此使用到的表,可以对其进行缓存,使用 sqlContext.cacheTable(tableName),或者DataFrame.cache()即可,spark-SQL会用内存列存储的格式进行表的缓存,然后spark-sql就可以仅仅扫描需要使用的列,并且自动优化压缩,来最小化内存使用和GC开销,SQLContext.uncacheTable(tableName)可以将表从缓存中移除,用SQLContext。setConf(),设置spark.sql.inMemoryColumnarStorage.batchSize参数(默认10000),可以设置列存储的单位
6)、广播join表:spark.sql.autoBroadcastJoinThreshold,默认10485760 (10 MB)。在内存够用的情况下,可以增加其大小,参数设置了一个表在join的时候,最大在多大以内,可以被广播出去优化性能

5、Hive on Spark配置
1)、安转配置好Hive和Spark
2)、Set hive.execution.engine=spark;
3)、set spark.master=spark://mini1:7077

具体怎么读取数据?

读取数据的API
JSON
PARQUET
JDBC
RDD
HIVE

RDD -> DataFrame -> 注册成临时表–》写sql
Hive :HiveContext
并不是在操作hive,hive只是给他提供了数据源
Hive on spark
Spark on hive

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值