A. 源码级解读如何解决Spark-sql读取hive分区表执行效率低问题
问题描述
在开发过程中使用spark去读取hive分区表的过程中(或者使用hive on spark、nodepad开发工具),部分开发人员未注意添加分区属性过滤导致在执行过程中加载了全量数据,引起任务执行效率低、磁盘IO大量损耗等问题。
解决办法
1、自定义规则CheckPartitionTable类,实现Rule,通过以下方式创建SparkSession。
2、自定义规则CheckPartitionTable类,实现Rule,将规则类追加至Optimizer.batches: Seq[Batch]中,如下。
规则内容实现
1、CheckPartitionTable规则执行类,需要通过引入sparkSession从而获取到引入conf;需要继承Rule[LogicalPlan];
2、通过splitPredicates方法,分离分区谓词,得到分区谓词表达式。在sql解析过程中将谓词解析为TreeNode,此处采用递归的方式获取分区谓词。
3、判断是否是分区表,且是否添加分区字段。
4、实现Rule的apply方法
大数据和云计算的关系
大数据JUC面试题
大数据之Kafka集群部署
大数据logstsh架构
大数据技术kafka的零拷贝
B. 【数仓】对比spark-hive的两种分布式计算模式
最近在学习过程中发现SparkSQL、Hive on Spark、Spark on Hive是非常容易混淆的的概念。了解三者的关系前,先要先明白几个概念。
相对于HIve on MapRece,本质上来说,Hive on Spark是Hive把自己的引擎从MapRece替换为更高效的SparkRDD。数据源是hive本身,当我们执行HQL时底层已经不再是将HQL转换为MapRece任务,而是跑SparkRDD任务。
在hive-site-xml中把hive.execution.engine配置换成spark,在hive所在节点安装Spark并配置环境变量。外部远程登录或者hive命令行模式就会执行spark任务了。
即:Hive on Spark = HQL解析 + SparkRDD引擎
Spark on Hive是以Spark角度看Hive是数据源,在Spark中配置Hive,并获取Hive中的元数据,然后用SparkSQL操作hive表的数据并直接翻译成SparkRDD任务。Hive只是作为一个Spark的数据源。
bin/spark-sql、bin/spark-submit采用的是这种方式。提交任务的jar必须带着hive-site.xml的配置。
即:Spark on Hive = SparkSql解析 + SparkRDD引擎
Spark on Hive的模式更加丝滑,性能更好。
HIve on Spark的模式对大数据周边组件的支持兼容性更好。
C. SparkSQL同步Hbase数据到Hive表
spark 2.3.0
hive 3.0.0
hbase 2.0.0
常规操作 hbase数据同步到hive是蚂搭通过再hive端建立hbase的映射表。
但是由于集群组件问题,建立的枣物笑映射表不能进行
insert into A select * from hbase映射表
操作。报错!
org.apache.hadoop.hbase.client.RetriesExhaustedException: Can't get the location for replica 0
at org.apache.hadoop.hbase.client..getRegionLocations(.java:332)
spark读取hbase数据形成RDD,构建schma信息,形成DF
通过sparkSQL 将df数据写入到指定的hive表格中。
hadoop本地环境版本一定要与依赖包版本保持一直,不然报如下错误
java.lang.IllegalArgumentException: Unrecognized Hadoop major version number: 3.1.1
hbase 1.X与2.X有很大差距,所以再看案例参考是一定要结合自己的hbase版本。
笔者程序编译中遇到
Cannot Resolve symbol TableInputFormat HBase找不到TableInputFormat
因为:新版本2.1.X版本的HBASE又把maprece.TableInputFormat单独抽取出来了
需要导入依赖
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-maprece</artifactId>
<version>${hbase.version}</version>
</dependency>
一定要把hbase相关凳含的包都cp 到spark的jars文件下面。然后重启spark服务。
不然你会遇到此类错误
Class org.apache.hadoop.hive.hbase.HBaseSerDe not found
或者
java.lang.NoClassDefFoundError: org/apache/hadoop/hbase/HBaseConfiguration
这些都是缺少jar包的表现。
D. Spark SQL写入Hive,同分区overwrite,不同分区insert
摘要: Spark SQL , Hive
新建hive表,定隐源义好字段类型和 分区字段
将DataFrame创建为视图表,创建一个分区字符串对象,使用 insert overwrite 指定 partition(dt=????) 进行指定分区的overwrite操作
建表之后test为一张空表,分别指定三次插入overwrite操作,dt分别为灶悉态"陆衡20201203","20201203","20201208",最终结果只有两个分区的数据
E. Spark SQL(十):Hive On Spark
Hive是目前大数据领域,事实上的SQL标准。其底层默认是基于MapRece实现的,但是由于MapRece速度实在比较慢,因此这几年,陆续出来了新的SQL查询引擎,包括Spark SQL,Hive On Tez,Hive On Spark等。
Spark SQL与Hive On Spark是不一样的。Spark SQL是Spark自己研发出来的针对各种数据源,包括Hive、JSON、Parquet、JDBC、RDD等都可以执行查询的,一套基于Spark计算引擎的查询引擎。因此它是Spark的一个项目,只不过提供了针对Hive执行查询的工功能而已,适合在一些使用Spark技术栈的大数据应用类系统中使用。
而Hive On Spark,是Hive的一个项目,它是将Spark作为底层的查询引擎(不通过MapRece作为唯一的查询引擎)。Hive On Spark,只适用于Hive,在可预见的未来,很有可能Hive默认的底层引擎就从MapRece切换为Spark了;适合于将原有的Hive数据仓库以及数据统计分析替换为Spark引擎,作为全公司通用的大数据统计分析引擎。
Hive On Spark做了一些优化:
1、Map Join
Spark SQL默认对join是支持使用broadcast机制将小表广播到各个节点上,以进行join的。但是问题是,这会给Driver和Worker带来很大的内存开销。因为广播的数据要一直保留在Driver内存中。所以目前采取的是,类似乎MapRece的Distributed Cache机制,即提高HDFS replica factor的复制因子,以让数据在每个计算节点上都有一个备份,从而可以在本地进行数据读取。
2、Cache Table
对于某些需要对一张表执行多次操作的场景,Hive On Spark内部做了优化,即将要多次操作的表cache到内存中,以便于提升性能。但是这里要注意,并不是对所有的情况都会自动进行cache。所以说,Hive On Spark还有很多不完善的地方。
Hive QL语句 =>
语法分析 => AST =>
生成逻辑执行计划 => Operator Tree =>
优化逻辑执行计划 => Optimized Operator Tree =>
生成物理执行计划 => Task Tree =>
优化物理执行计划 => Optimized Task Tree =>
执行优化后的Optimized Task Tree
F. sparkSQL用jdbc连接hive和用元数据连接hive的区别,各自优缺点
spark on hive : 是spark 通过spark-sql 使用hive 语句操作hive ,底层运行的还是 spark rdd.
*(1)就是通过sparksql,加载hive的配置文件,获取到hive的元数据信息
* (2)spark sql获取到hive的元数据信息之后就可以拿到hive的所有表的数据
* (3)接下来就可以通过spark sql来操作hive表中的数据
hive on spark: 是hive 等的执行引擎变成spark , 不再是maprece. 相对于上一项,这个要实现责麻烦很多, 必须重新编译你的spark. 和导入jar包,
G. spark sql怎么去获取hive 表一定日期范围内的数据
select orderid,fenjian,timee
from
(
select orderid,fenjian,timee,row_number(orderid,fenjian) rn
from (
select orderid,fenjian,timee from tableName
distribute by orderid,fenjian sort by orderid,fenjian,timee asc
) t1
) t2
where t2.rn=1