Hive性能优化及Hive3新特性
Hive表设计优化
Hive查询基本原理
Hive的设计思想是通过元数据解析描述将HDFS上的文件映射成表
基本的查询原理是当用户通过HQL语句对Hive中的表进行复杂数据处理和计算时,默认将其转换为分布式计算 MapReduce程序对HDFS中的数据进行读取处理的过程
。
分区表结构设计
create table t_all_hero_part(
id int,
name string,
hp_max int,
mp_max int,
attack_max int,
defense_max int,
attack_range string,
role_main string,
role_assist string
) partitioned by (role string)
row format delimited
fields terminated by "\t";
-- 分区表 先基于分区过滤,再查询;基于分区扫描,避免全表扫描,大大提高查询效率;若查询时使用的不是分区字段,将无任何意义
explain extended select count(*) from t_all_hero_part where role="sheshou" and hp_max>6000;
分桶表结构设计
Hive中Join的问题
- 默认情况下,Hive底层是通过MapReduce来实现的;
- MapReduce在处理数据之间join的时候有两种方式:MapJoin、ReduceJoin,其中MapJoin效率较高;
- 如果有
两张非常大的表要进行Join
,底层无法使用MapJoin提高Join的性能,只能走默认的ReduceJoin
; - 而ReduceJoin必须经过
Shuffle过程,相对性能比较差
,而且容易产生数据倾斜
。
分桶表设计
- 如果有
两张表按照相同的划分规则
【比如按照Join的关联字段】将各自的数据进行划分; - 在Join时,就可以实现
Bucket与Bucket的Join
,避免不必要的比较,减少笛卡尔积数量。
-- 开启分桶SMB(Sort-Merge-Bucket) join
set hive.optimize.bucketmapjoin = true;
set hive.auto.convert.sortmerge.join=true;
set hive.optimize.bucketmapjoin.sortedmerge=true;
select * from t_usa_covid19_bucket;
-- 分桶表创建
create table tb_emp02(
empno string,
ename string,
job string,
managerid string,
hiredate string,
salary double,
jiangjin double,
deptno string
)clustered by(deptno) sorted by(deptno asc) into 3 buckets
row format delimited fields terminated by '\t';
create table tb_dept02(
deptno string,
dname string,
loc string
)clustered by(deptno) sorted by (deptno asc) into 3 buckets
row format delimited fields terminated by ',';
索引的设计及注意事项
Hive中的索引
-
在传统的关系型数据库例如MySQL、0racle中,为了提高数据的查询效率,可以
为表中的字段单独构建索引
,查询时,可以基于字段的索引快速的实现查询、过滤
等操作。 -
Hive中也同样提供了索引的设计,允许用户为字段构建索引,提高数据的査询效率,但是Hive的索引与关系型数据库中的索引并不相同,比如,
Hive不支持主键或者外键索引
。 -
Hive索引可以建立在表中的某些列上,以提升一些操作的效率。
-
在可以预见到分区数据非常庞大的情况下,分桶和索引常常是优于分区的;
-
而分桶由于SMB Join对关联键(join字段)要求严格,所以并不是总能生效;
-
注意:官方明确表示,索引功能支持是从Hive0.7版本开始,到
Hive3.0不再支持
。
Hive中索引的基本原理
当为某张表的某个字段创建索引时,Hive中会自动创建一张索引表
,该表记录了该字段的每个值与数据实际物理位置之间的关系
,例如数据所在的HDFS文件地址,以及所在文件中偏移量offset等信息
Hive索引目的
提高Hive表指定列的查询速度。没有索引时,类似WHERE tab1.col1 = 10的查询,Hive会加载整张表或分区,然后处理所有的行,但是如果在字段col1上面存在索引时,那么只会加载和处理文件的一部分。
-- 为表中的userid构建索引
create index idx_user_id_login on table tb_login_part(userid)
-- 索引类型为Compact,Hive支持Compact和Bitmap类型,存储的索引内容不同
as 'COMPACT'
-- 延迟构建索引
with deferred rebuild;
-- 构建索引
alter index idx_user_id_login on tb_login_part rebuild;
-- 查看索引结构
desc default__tb_login_part_idx_user_id_login__;
-- 查看索引内容
select * from default__tb_login_part_idx_user_id_login__;
Hive索引的问题
- Hive
构建索引
的过程是通过一个MapReduce程序来实现的
- 每次Hive中原始数据表的数据发生更新时,索引表不会自动更新;
- 必须手动执行一个alter index命令来实现通过MapReduce更新索引表,导致整体性能较差,维护相对繁琐
- 实际工作场景中,一般不推荐使用HiveIndex,
推荐使用0RC文件格式中的索引
、物化视图
来代替Hive Index提高查询性能。
Hive表数据优化
文件格式
概述
Hive数据存储的本质还是HDFS,所有的数据读写都基于HDFS的文件来实现;
为了提高对HDFS文件读写的性能,Hive提供了多种文件存储格式:TextFile、SequenceFile、0RC、Parquet
等
不同的文件存储格式具有不同的存储特点,有的可以降低存储空间,有的可以提高查询性能。
Hive的文件格式在建表时指定,默认是TextFile。
官方文档:Apache Hive - Storage Formats
除了文件格式TextFile可以额外使用load命令插入数据外,其余格式均只能采用insert+select动态插入数据
文件格式-TextFile
- TextFile是Hive中
默认的文件格式
,存储形式为按行存储
。 - 工作中最常见的数据文件格式就是TextFile文件,几乎所有的原始数据生成都是TextFile格式,所以Hive设计时考虑到为了避免各种编码及数据错乱的问题,选用了TextFile作为默认的格式。
- 建表时不指定存储格式即为TextFile,导入数据时把数据文件拷贝至HDFS不进行处理。
文件格式-SequenceFile
- SequenceFile是Hadoop里用来
存储序列化的键值对即二进制
的一种文件格式。 - SequenceFile文件也可以作为MapReduce作业的输入和输出,hive也支持这种格式。
文件格式-Parquet
- Parquet是一种支持嵌套结构的
列式存储
文件格式,最早是由Twitter和Cloudera合作开发,2015年5月从Apache孵化器里毕业成为Apache顶级项目。 - 是一种
支持嵌套数据模型对的列式存储系统
,作为大数据系统中0LAP查询的优化方案,它已经被多种查询引擎原生支持,并且部分高性能引擎将其作为默认的文件存储格式
。 - 通过
数据编码和压缩
,以及映射下推和谓词下推
功能,Parquet的性能也较之其它文件格式有所提升。
文件格式-ORC
- 0RC(0ptimizedRc File)文件格式也是一种Hadoop生态圈中的
列式存储格式
; - 它的产生早在2013年初,最初产生自Apache Hive,用于降低Hadoop数据存储空间和加速Hive查询速度;
- 2015年0RC项目被Apache项目基金会提升为Apache顶级项目。
- 0RC不是一个单纯的列式存储格式,仍然是
首先根据行组分割整个表,在每一个行组内进行按列存储
。 - 0RC文件是自描述的,它的元数据使用Protocol Buffers序列化,并且文件中的数据尽可能的
压缩以降低存储空间的消耗
,目前也被Hive、Spark SQL、Presto等查询引擎支持。
数据压缩
概述
- Hive底层运行llapReduce程序时,磁盘I/O操作、网络数据传输、shuffle和merge要花大量的时间,尤其是数据规模很大和工作负载密集的情况下,
- 鉴于磁盘I/0和网络带宽是Hadoop的宝贵资源,
数据压缩对于节省资源、最小化磁盘I/0和网络传输
非常有帮助。 - Hive压缩实际上说的就是MapReduce的压缩。
-
压缩的优点
-
减小文件存储所占空间
-
加快文件传输效率,从而提高系统的处理速度
-
降低IO读写的次数
-
-
压缩的缺点
- 使用数据时需要先对文件解压,加重CPU负荷,压缩算法越复杂,解压时间越长
Hive中压缩
-
Hive中的压缩就是使用了Hadoop中的压缩实现
的,所以Hadoop中支持的压缩在Hive中都可以直接使用。 -
Hadoop中支持的压缩算法:
-
要想在Hive中使用压缩,需要对MapReduce和Hive进行相应的配置。
-
Hadoop中各种压缩算法性能对比
Hive中压缩配置
-- 开启hive中间传输数据压缩功能
-- 1)开启hive中间传输数据压缩功能
set hive.exec.compress.intermediate=true;
-- 2)开启mapreduce中map输出压缩功能
set mapreduce.map.output.compress=true;
-- 3)设置mapreduce中map输出数据的压缩方式
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
-- 开启Reduce输出阶段压缩
-- 1)开启hive最终输出数据压缩功能
set hive.exec.compress.output=true;
-- 2)开启mapreduce最终输出数据压缩
set mapreduce.output.fileoutputformat.compress=true;
-- 3)设置mapreduce最终数据输出压缩方式
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
-- 4)设置mapreduce最终数据输出压缩为块压缩
set mapreduce.output.fileoutputformat.compress.type=BLOCK;
Hive中压缩测试
测试1:
测试2:
存储优化
避免小文件生成
- Hive的存储本质还是HDFS,HDFS是d不利于小文件存储的,因为
每个小文件会产生一条元数据信息
,并且不利用MapReduce的处理,MapReduce中每个小文件会启动一个MapTask
计算处理,导致资源的浪费
,所以在使用Hive进行处理分析时,要尽量避免小文件的生成
。 - Hive中提供了一个特殊的机制,可以
自动的判断是否是小文件
,如果是小文件可以自动将小文件进行合并
。
-- 如果hive的程序,只有maptask,将MapTask产生的所有小文件进行合并
set hive.merge.mapfiles=true;
-- 如果hive的程序,有Map和ReduceTask,将ReduceTask产生的所有小文件进行合并
set hive.merge.mapredfiles=true;
-- 每一个合并的文件的大小(244M)
set hive.merge.size.per.task=256000000
-- 平均每个文件的大小,如果小于这个值就会进行合并(15M)
set hive.merge.smallfiles.avgsize=16000000;
合并小文件
- 如果遇到数据处理的
输入是小文件
的情况,怎么解决呢? Hive中也提供一种输入类CombineHiveInputFormat
,用于将小文件合并以后,再进行处理
。
-- 设置Hive中底层MapReduce读取数据的输入类:将所有文件合并为一个大文件作为输入
set hive.input.format=org.apache.hadoop.hive.gl.io.CombineHiveInputFormat;
ORC文件索引
- 在使用ORC文件时,为了加快读取0RC文件中的数据内容,0RC提供了两种索引机制:
Row Group Index
和Bloom Filter Index
可以帮助提高查询0RC文件的性能。 - 当用户写入数据时,可以指定构建索引当用户查询数据时,可以
根据索引提前对数据进行过滤,避免不必要的数据扫描
。
Row Group Index
- 一个ORC文件包含一个或多个stripes(groups ofrow data),每个stripe中包含了每个column的min/max值的索引数据;
当查询中有大于等于小于的操作时,会根据min/max值,跳过扫描不包含的stripes
。- 而其中为
每个stripe建立的包含min/max值的索引,就称为Row Group Index行组索引
,也叫min-maxIndex大小对比索引,或者Storage Index。
- 建立ORC格式表时,指定表参数
orc.create.index=true
之后,便会建立Row Group Index; - 为了使Row Group Index有效利用,向表中加载数据时,
必须对需要使用索引的字段进行排序
Bloom Filter Index
- 建表时候通过表参数
orc.bloom.fllter.columns=columnName...
来指定为哪些字段建立BloomFilter索引,在生成数据的时候,会在每个stripe中,为该字段建立BloomFilter的数据结构; - 当
查询条件中包含对该字段的等值过滤时候
,先从BloomFilter中获取以下是否包含该值,如果不包含,则跳过该stripe。
ORC矢量化查询
- Hive的
默认查询执行引擎一次处理一行
,而矢量化査询执行是一种Hive针对ORC文件
操作的特性,目的是按照每批1024行读取数据
,并且一次性对整个记录整合
(而不是对单条记录)应用操作,提升了像过滤、联合、聚合等等操作的性能。 - 注意:要使用矢量化查询执行,就必须以
ORC格式存储数据
。
-- 开启矢量化查询
set hive.vectorized.execution.enabled = true;
set hive.vectorized.execution.reduce.enabled = true;
Job作业执行优化
Explain查询计划
HiveQL是一种类SQL的语言,从编程语言规范来说是一种声明式语言,用户会根据査询需求提交声明式的HQL查询而Hive会根据底层计算引警将其转化成Mapreduce/Tez/Spark的job;
explain命令可以帮助用户了解一条HQL语句在底层的实现过程。通俗来说就是Hive打算如何去做这件事。
explain会解析HQL语句,将整个HQL语句的实现步骤、依赖关系、实现过程
都会进行解析返回,可以了解一条HQL语句在底层是如何实现数据的查询及处理的过程,辅助用户对Hive进行优化。
官网:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Explain
常用语法命令如下:
EXPLAIN [FORMATTED | EXTENDED | DEPENDENCY | AUTHORIZATION] query
-
FORMATTED:对执行计划进行格式化,返回JSON格式的执行计划
-
EXTENDED:提供一些额外的信息,比如文件的路径信息
-
DEPENDENCY:以JSON格式返回查询所依赖的表和分区的列表
-
AUTHORIZATION:列出需要被授权的条目,包括输入与输出
-
每个查询计划由以下几个部分组成
-
The Abstract Syntax Tree for the query
抽象语法树(AST)
:Hive使用Antlr解析生成器,可以自动地将HQL生成为抽象语法树 -
The dependencies between the different stages of the plan
Stage依赖关系
:会列出运行查询划分的stage阶段以及之间的依赖关系 -
The description of each of the stages
Stage内容
:包含了每个stage非常重要的信息,比如运行时的operator和sort orders等具体的信息
示例:
explain select count(*) as cnt from tb_emp where deptno ='10';
MapReduce属性优化
本地模式
-
使用Hive的过程中,有一些
数据量不大的表也会转换为MapReduce处理
,提交到集群时,需要申请资源,等待资源分配,启动J进程,再运行Task,一系列的过程比较繁琐
,本身数据量并不大,提交到YARN运行返回会导致性能较差
的问题。 -
Hive为了解决这个问题,延用了MapReduce中的设计,提供
本地计算模式
,允许程序不提交给YARN
,直接在本地运行,以便于提高小数据量程序
的性能。 -
开启本地模式
-- 开启本地模式 set hive.exec.mode.local.auto = true;
JVM重用
- Hadoop
默认会为每个Task启动一个JVM来运行
,而在JVM启动时内存开销大; - Job数据量大的情况,如果单个Task数据量比较小,也会申请JVM,这就导致了资源紧张及浪费的情况;
- JVM重用可以使得JVM实例在同一个job中重新使用N次,当一个Task运行结束以后,IM不会进行释放,而是继续供下一个Task运行,直到运行了N个Task以后,就会释放;
- N的值可以在Hadoop的mapred-site.xml文件中进行配置,通常在10-20之间。
-- Hadoop3之前的配置,在mapred-site.xml中添加以下参数
-- Hadoop3中已不再支持该选项
mapreduce.job.jvm.numtasks=10
并行执行
- Hive在实现HQL计算运行时,会解析为多个Stage,有时候Stage彼此之间有依赖关系,只能挨个执行,但是在一些别的场景下,很多的Stage之间是没有依赖关系的;
- 例如Union语句,Join语句等等,这些Stage没有依赖关系,但是
Hive依旧默认挨个执行每个Stage
,这样会导致性能非常差
,我们可以通过修改参数,开启并行执行,当多个Stage之间没有依赖关系
时,允许多个Stage并行执行
,提高性能。
-- 开启Stage并行化,默认为false
SET hive.exec.parallel=true;
-- 指定并行化线程数,默认为8
SET hive.exec.parallel.thread.number=16;
Join查询优化
- Join是数据分析处理过程中必不可少的操作,Hive同样支持Join的语法;
- Hive Join的底层是通过MapReduce来实现的,Hive实现Join时,为了提高MapReduce的性能,提供了多种Join方案来实现;
- 例如适合
小表Join大表的Map Join
,大表Join大表的Reduce Join
,以及大表Join的优化方案Bucket Join
等。
Map Join
应用场景:适合于小表join大表或者小表Join小表
原理:将小的那份数据给每个MapTask的内存都放一份完整的数据,大的数据每个部分都可以与小数据的完整数据进行join;底层不需要经过shuffle
,需要占用内存空间存放小的数据文件
使用:尽量使用Map Join来实现Join过程,Hive中默认自动开启了Map Join
:hive.auto.convert.join=true
Hive中小表的大小限制
-- 2.0版本之前的控制属性
hive.mapjoin.smalltable.filesize=25M
-- 2.0版本开始由以下参数控制
hive.auto.convert.join.noconditionaltask.size=512000000
Reduce Join
应用场景:适合于大表join大表
原理:将两张表的数据在shuffle阶段利用shuffle的分组
来将数据按照关联字段进行合并;必须经过shuffle
,利用Shuffle过程中的分组来实现关联
使用:Hive会自动判断是否满足Map Join
,如果不满足Map Join,则自动执行Reduce Join
Bucket Join
应用场景:适合于大表Join大表
原理:将两张表按照相同的规则将数据划分,根据对应的规则的数据进行join,减少了比较次数,提高了性能
使用Bucket Join
语法:clustered by colName
参数:set hive.optimize.bucketmapjoin = true;
要求:分桶字段 = Join字段,桶的个数相等或者成倍数
使用Sort Merge Bucket Join(SMB)
基于有序的数据Join
语法:clustered by colName sorted by(colName)
参数
set hive.optimize.bucketmapjoin = true, set hive.auto.convert.sortmerge.join=true, set hive.optimize.bucketmapjoin.sortedmerge = true; set hive.auto.convert.sortmerge.join.noconditionaltask=true;
要求:分桶字段=Join字段=排序字段,桶的个数相等或者成倍数
优化器
关联优化
当一个程序中如果有一些操作彼此之间有关联性
,是可以在一个MapReduce中实现的,但是Hive会不智能的选择
,Hive会使用两个MapReduce来完成这两个操作。
例如:当我们执行 select. from table group by id order by id desc。该SQL语句转换为MapReduce时我们可以有两种方案来实现:
-
方案一
第一个MapReduce做group by,经过shuffle阶段对id做分组
第二个MapReduce对第一个MapReduce的结果做order by,经过shuffle阶段对id进行排序
-
方案二
因为都是对id处理,可以使用一个MapReduce的shuffle既可以做分组也可以排序
在这种场景下,Hive会默认选择用第一种方案来实现
,这样会导致性能相对较差
;
可以在Hive中开启关联优化,对有关联关系的操作进行解析时,可以尽量放在同一个MapReduce中实现。
配置:set hive.optimize.correlation=true;
优化器引擎
- Hive
默认的优化器
在解析一些聚合统计类的处理时,底层解析的方案有时候不是最佳的方案
。 - 例如当前有一张表【共1000条数据】,id构建了索引,id =100值有900条
需求:查询所有id =100的数据,SQL语句为:select * from table where id = 100; - 方案一
由于id这一列构建了索引,索引默认的优化器引擎RBO
,会选择先从索引中査询id = 100的值所在的位置,再根据索引记录位置去读取对应的数据,但是这并不是最佳的执行方案。 - 方案二
有id=100的值有900条,占了总数据的90%,这时候是没有必要检索索引以后再检索数据的,可以直接检索数据返回,这样的效率会更高,更节省资源,这种方式就是CBO优化器引擎会选择的方案
。
CBO优化器
-
RBO:
rule basic optimise,基于规则的优化器
,根据设定好的规则来对程序进行优化 -
CBO:
cost basic optimise,基于代价的优化器
,根据不同场景所需要付出的代价来合适选择优化的方案
对数据的分布的信息【数值出现的次数,条数,分布】来综合判断用哪种处理的方案是最佳方案
-
Hive中支持RBO与CBO这两种引擎,默认使用的是RBO优化器引擎。
-
很明显CBO引擎更加智能,所以在使用Hive时,我们可以配置底层的优化器引擎为CBO引擎
set hive.cbo.enable=true;
set hive.compute.query.using.stats=true;
set hive.stats.fetch.column.stats=true;
CBO引擎是基于代价的优化引擎,那么CBO如何知道每种方案的计算代价的呢 ?
答:如下的分析器。
Analyze分析器
功能:用于提前运行一个MapReduce程序将表或者分区的信息构建一些元数据
【表的信息、分区信息、列的信息】,搭配CBO引擎一起使用。
语法:
示例:
-- Analyze分析优化器
analyze table tb_emp02 compute statistics;
analyze table tb_emp02 compute statistics for columns empno;
desc formatted tb_emp02 empno;
谓词下推(PPD)
谓词:用来描述或判定客体性质、特征或者客体之间关系的词项。比如"3 大于 2"中"大于"是一个谓词。
谓词下推Predicate Pushdow(PPD)
基本思想:将过滤表达式尽可能移动至靠近数据源的位置,以使真正执行
时能直接跳过无关的数据。简单点说就是在不影响最终结果的情况下,尽量将过滤条件提前执行
。
Hive中谓词下推后,过滤条件会下推到map端,提前执行过滤,减少map到reduce的传输数据
,提升整体性能。
开启参数【默认开启】:hive.optimize.ppd=true;
例子:推荐形式1的方式,先过滤再join。
规则
1、对于Join(Inner Join)、Full outer Join,条件写在on后面,还是where后面,性能上面没有区别;
2、对于Left outer Join,右侧的表写在on后面、左侧的表写在where后面,性能上有提高;
3、对Right outer Join,左侧的表写在on后面、右侧的表写在where后面,性能上有提高;
4、当条件分散在两个表时,谓词下推可按上述结论2和3自由组合。
数据倾斜
分布式计算中最常见的,最容易遇到的问题就是数据倾斜;
数据倾斜的现象是,当提交运行一个程序时,这个程序的大多数的Task都已经运行结束了
,只有某一个 Task一直在运行
,迟迟不能结束,导致整体的进度卡在99%或者100%
,这时候就可以判定程序出现了数据
倾斜的问题。
数据倾斜的原因:数据分配。
Group By倾斜优化
- 当程序中出现group by或者count(distinct)等分组聚合的场景时,如果数据本身是倾斜的,根据MapReduce的Hash分区规则,肯定会出现数据倾斜的现象。
- 根本原因是因为分区规则导致的,所以可以通过以下几种方案来解决group by导致的数据倾斜的问题
方案一:开启Map端聚合
hive.map.aggr=true;
通过减少shuffle数据量和Reducer阶段的执行时间,避免每个Task数据差异过大导致数据倾斜
方案二:实现随机分区
select * from table distribute by rand();
distribute by用于指定底层按照哪个字段作为Key实现分区、分组等
通过rank函数随机值实现随机分区,避免数据倾斜
方案三:数据倾斜时自动负载均衡
hive.groupby.skewindata=true;
开启该参数以后,当前程序会自动通过两个MapReduce来运行
第一个MapReduce自动进行随机分布到Reducer中,每个Reducer做部分聚合操作,输出结果
第二个MlapReduce将上一步聚合的结果再按照业务(group by key)进行处理,保证相同的分布到一起,最终聚合得到结果
Join倾斜优化
- Join操作时,如果两张表比较大,无法实现Map Join,只能走
Reduce Join,那么当关联字段中某一种值 过多的时候依旧会导致数据倾斜的问题
- 面对Join产生的数据倾斜,核心的思想是
尽量避免Reduce Join的产生
,优先使用Map Join来实现; - 但往往很多的Join场景不满足Map Join的需求,那么可以以下几种方案来解决Join产生的数据倾斜问题
方案一:提前过滤,将大数据变成小数据,实现Map Join
方案二:使用Bucket Join
如果使用方案一,过滤后的数据依旧是一张大表,那么最后的Join依旧是一个Reduce Join
这种场景下,可以将两张表的数据构建为桶表,实现Bucket Map Join,避免数据倾斜
方案三:使用Skew Join
Skew Join是Hive中一种专门为了避免数据倾斜而设计的特殊的Join过程
这种Join的原理是将Map Join和Reduce Join进行合并,如果某个值出现了数据倾斜
,就会将产生数据倾斜的数据单独使用Map Join来实现
其他没有产生数据倾斜的数据由Reduce Join
来实现,这样就避免了Reduce Join中产生数据倾斜的问题
最终将Map Join的结果和Reduce Join的结果进行Union合并
开启配置:
-- 开启运行过程中skewjoin
set hive.optimize.skewjoin=true,
-- 如果这个key的出现的次数超过这个范围
set hive.skewjoin.key=100000.
-- 在编译时判断是否会产生数据倾斜
set hive.optimize.skewjoin.compiletime=true;
-- 不合并,提升性能
set hive.optimize.union.remove=true;
-- 如果Hive的底层走的是MapReduce,必须开启这个属性,才能实现不合并
set mapreduce.input.fileinputformat.input.dir.recursive=true;
Hive3新特性
执行引擎
Hive执行引擎
Hive底层的计算由分布式计算框架实现,目前支持三种计算引擎,分别是MapReduce、Tez、Spark。
Hive中默认的计算引擎是MapReduce
,由hive.execution.engine
参数属性控制。
Hive从2.x版本开始就提示不推荐使用MR,未来的版本可能不能使用了,推荐使用Tez或者Spark
引擎来代替MapReduce计算。如果依旧要使用MapReduce,需要使用Hive的1.x版本。
通过实测发现,当下Hive3.1.2版本默认引擎依然是MapReduce。
在实际使用Hive的过程中,建议将Hive的底层计算引擎更改为Tez或者Spark引擎。
Hive On Tez
Tez是Apache社区中的一种支持DAG作业
的开源计算框架;
可以将多个有依赖的作业转换为一个作业从而大幅提升DAG作业的性能,最终Tez也会将程序提交给YARN
来
实现运行。
Tez并不直接面向最终用户
,事实上它允许开发者为最终用户构建性能更快、扩展性更好的应用程序。
Tezt特点:
- 灵活的数据流定义
- 灵活的输入、输出、运行时模型
- 与数据类型无关
- 部署方便简洁
- 高性能执行:
- 最佳资源管理
- 计划配置动态更新
- 动态物理数据流决策
官网:http://tez.apache.org/
Tez整体的执行过程如图所示:
- Hive编译SQLTez执行查询
- YARN分配资源,支撑Tez执行
- Hive表数据文件默认存储在HDFS
- Tez执行完毕返回查询结果给Hive
(1)Tez下载
目前官方http://archive.apache.org/dist/tez/最新版本为0.9系列版本,0.9系列版本为针对Hadoop2.x系列的版本,我们使用的Hadoop为3.x版本,可以使用GitHub中已发布的0.10版本的tez。
(2)Tez编译
0.10不是正式版本,针对Hadoop3需要单独手动编译、可以使用提前编译好的安装包,也可以参考编译文
档进行编译。【可参考末尾资料】
编译结果如下:
(3)Tez安装
编译完成之后,提取Tez的安装包进行安装,并在Hadoop中和Hive中配置【可参考末尾资料】
tez-0.10.1-SNAPSHOT-minimal.tar.gz:程序安装包
tez-0.10.1-SNAPSHOT.tar.gz:程序依赖包
相关资料下载:https://pan.baidu.com/s/1IzsMte_sCj2zaFqfxyw_Hg 提取码: hdq5
-- 设置执行引擎为Tez
set hive.execution.engine=tez;
set hive.tez.container.size=1024;
如果想一直使用tez执行 可以把上述参数添加在hive-site.xml中:
<property>
<name>hive.execution.engine</name>
<value>tez</value>
</property>
<property>
<name>hive.tez.container.size</name>
<value>1024</value>
</property>
LLAP特性更新
-
LLAP是hive 2.0版本就引入的特性,
在Hive 3中与Tez集成的应用更加成熟
-
Hive官方称之为
实时长期处理(Live long and process)
,实现将数据预取、缓存到基于yarn运行的守护进程
中,降低和减少系统IO和与HDFS DataNode的交互,以提高程序的性能
,LLAP 目前只支持tez引擎。 -
LLAP提供了一种混合执行模型。它由一个长期存在的守护进程(该守护进程替换了与 HDFS DataNode 的直接交互)以及一个紧密集成的基于 DAG 的框架组成。诸如缓存,预取,某些查询处理和访问控制之类的功能已移至守护程序中。
-
此守护程序直接直接处理小/短查询,而任何繁重的工作都将在标准 YARN 容器中执行。
-
与DataNode相似,LLAP 守护程序也可以由其他应用程序使用。
-
Tez AM 统筹整体执行,查询的初始阶段被推送到 LLAP 中,在还原阶段,将在单独的容器中执行大型
Shuffle,多个查询和应用程序可以同时访问 LLAP。
-
LLAP 在现有的Hive基于流程的执行中工作,以保持ive的可伸缩性和多功能性。它
不会替代现有的执行模型,而是对其进行了增强
。它有如下的几个特点:LLAP守护程序是可选的
- Hive可以在没有LLAP的情况下工作,并且即使已经部署并启动运行LLAP也可以绕过不执行
LLAP不是执行引擎
- 不同于MapReduce 或 Tez,整个执行由现有的 Hive 执行引擎(例如 Tez)在 LLAP 节点以及常规容器上透明地调度和监控。显然,LLAP的支持级别取决于单独的执行引擎。不计划支持 MapReduce,但以后可能会添加其他引擎,例如Pig等其他框架也可以选择使用 LLAP 守护程序。
- 部分执行
- LLAP守护程序执行的工作结果可以构成 Hive 查询结果的一部分
- 资源源Management
- YARN仍然负责资源的管理和分配
-
Hive3增强了在多租户场景下的LLAP负载管理,主要通过resource plan的方式进行实现
划分LLAP资源为多个pool,比如dept_A池、dept_B池和其他池;
自动映射applications到对应的池
可以设置触发条件,实现自动从一个池到另一个池,比如自动把长时间运行的application移动到其它池
可以根据需要启用/禁用这些资源池
Metastore独立模式
- Hive中的所有对象如数据库、表、函数等,他们的定义都叫做metadata元数据。
- metastore是元数据存储服务,用于操作访问元数据。
- Hive或者
其他执行引擎在运行时会使用这些元数据
来决定如何解析、授权和有效地执行用户查询 - metadata元数据可以存储配置为嵌入式的Apache Derby RDBMS或连接到外部RDBMS。
- Metastore本身可以完全嵌入到用户进程中,也
可以作为服务运行,供其他进程连接
- 从Hive 3.0开始,
Metastore可以在不安装Hive其他部分的情况下单独运行
,作为一个单独的发行版提供,用于实现允许其他非Hive的系统,例如Spark、Impala等轻松地与Metastore集成。 - 目前来说为了方便起见,依旧建议将Metastore放在Hive中,一起安装部署。
- 从Hive 3.0开始,
Metastore作为一个单独的包发布
,可以在没有Hive其他部分的情况下运行。这称为独立模式
。 - 但是在默认情况下Metastore配置为与Hive一起使用,因此在这个配置中需要修改一些配置参数。
- 要使Metastore成为一个独立的服务,需要修改大量的参数,目前Hive官方为了最大限度地向后兼容,所有旧的配置参数仍然有效。Hive的Metastore服务将读取metastore-site.xml,同时也会从Hive的配置文件目录中读取hive-site.xml或者hive-memstoresite.xml女件
- 配置参数后,可以使用start-metastore.sh来启动metastore服务。
- 安装metastore独立安装包
- 修改metastore配置文件conf/metastore-site.xml
- 添加hive-site.xml以及MySQL连接驱动
- 删除冲突guava19包,添加Hive中的guava27包
- 启动独立metastore