【Hive】8-Hive性能优化及Hive3新特性

Hive性能优化及Hive3新特性

Hive表设计优化

Hive查询基本原理

Hive的设计思想是通过元数据解析描述将HDFS上的文件映射成表

基本的查询原理是当用户通过HQL语句对Hive中的表进行复杂数据处理和计算时,默认将其转换为分布式计算 MapReduce程序对HDFS中的数据进行读取处理的过程

分区表结构设计
sql 复制代码
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,避免不必要的比较,减少笛卡尔积数量。
sql 复制代码
-- 开启分桶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上面存在索引时,那么只会加载和处理文件的一部分。

sql 复制代码
-- 为表中的userid构建索引
create index idx_user_id_login on table tb_login_part(userid)
-- 索引类型为Compact,Hive支持Compact和Bitmap类型,存储的索引内容不同
as 'COMPACT'
-- 延迟构建索引
with deferred rebuild;
sql 复制代码
-- 构建索引
alter index idx_user_id_login on tb_login_part rebuild;

-- 查看索引结构
desc default__tb_login_part_idx_user_id_login__;
sql 复制代码
-- 查看索引内容
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中压缩配置
sql 复制代码
-- 开启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中提供了一个特殊的机制,可以自动的判断是否是小文件,如果是小文件可以自动将小文件进行合并
sql 复制代码
-- 如果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,用于将小文件合并以后,再进行处理
sql 复制代码
-- 设置Hive中底层MapReduce读取数据的输入类:将所有文件合并为一个大文件作为输入
set hive.input.format=org.apache.hadoop.hive.gl.io.CombineHiveInputFormat;
ORC文件索引
  • 在使用ORC文件时,为了加快读取0RC文件中的数据内容,0RC提供了两种索引机制:Row Group IndexBloom 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格式存储数据
sql 复制代码
-- 开启矢量化查询
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

常用语法命令如下:

sql 复制代码
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等具体的信息

示例:

sql 复制代码
explain select count(*) as cnt from tb_emp where deptno ='10';
MapReduce属性优化
本地模式
  1. 使用Hive的过程中,有一些数据量不大的表也会转换为MapReduce处理,提交到集群时,需要申请资源,等待资源分配,启动J进程,再运行Task,一系列的过程比较繁琐,本身数据量并不大,提交到YARN运行返回会导致性能较差的问题。

  2. Hive为了解决这个问题,延用了MapReduce中的设计,提供本地计算模式,允许程序不提交给YARN,直接在本地运行,以便于提高小数据量程序的性能。

  3. 开启本地模式

    sql 复制代码
    -- 开启本地模式
    set hive.exec.mode.local.auto = true;
JVM重用
  1. Hadoop默认会为每个Task启动一个JVM来运行,而在JVM启动时内存开销大;
  2. Job数据量大的情况,如果单个Task数据量比较小,也会申请JVM,这就导致了资源紧张及浪费的情况;
  3. JVM重用可以使得JVM实例在同一个job中重新使用N次,当一个Task运行结束以后,IM不会进行释放,而是继续供下一个Task运行,直到运行了N个Task以后,就会释放;
  4. N的值可以在Hadoop的mapred-site.xml文件中进行配置,通常在10-20之间。
sql 复制代码
-- Hadoop3之前的配置,在mapred-site.xml中添加以下参数
-- Hadoop3中已不再支持该选项
mapreduce.job.jvm.numtasks=10
并行执行
  1. Hive在实现HQL计算运行时,会解析为多个Stage,有时候Stage彼此之间有依赖关系,只能挨个执行,但是在一些别的场景下,很多的Stage之间是没有依赖关系的;
  2. 例如Union语句,Join语句等等,这些Stage没有依赖关系,但是Hive依旧默认挨个执行每个Stage,这样会导致性能非常差,我们可以通过修改参数,开启并行执行,当多个Stage之间没有依赖关系时,允许多个Stage并行执行,提高性能。
sql 复制代码
-- 开启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中小表的大小限制

sql 复制代码
-- 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引擎一起使用。

语法:

示例:

sql 复制代码
-- 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合并

开启配置:

sql 复制代码
-- 开启运行过程中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特点:

  1. 灵活的数据流定义
  2. 灵活的输入、输出、运行时模型
  3. 与数据类型无关
  4. 部署方便简洁
  5. 高性能执行:
  6. 最佳资源管理
  7. 计划配置动态更新
  8. 动态物理数据流决策

官网:http://tez.apache.org/

Tez整体的执行过程如图所示:

  1. Hive编译SQLTez执行查询
  2. YARN分配资源,支撑Tez执行
  3. Hive表数据文件默认存储在HDFS
  4. 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

sql 复制代码
-- 设置执行引擎为Tez
set hive.execution.engine=tez;
set hive.tez.container.size=1024;

如果想一直使用tez执行 可以把上述参数添加在hive-site.xml中:

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
相关推荐
F_Director17 分钟前
Webpack性能优化的理论和实践
前端·webpack·性能优化
临风赏月1 小时前
Hadoop、Kafka、Flink、Spark、Hive五大组件运维常用操作命令
hadoop·flink·kafka
七夜zippoe2 小时前
仓颉FFI实战:C/C++互操作与性能优化
c语言·c++·性能优化
笨蛋少年派12 小时前
Hive安装部署
数据仓库·hive·hadoop
冴羽12 小时前
10 个被严重低估的 JS 特性,直接少写 500 行代码
前端·javascript·性能优化
下一站丶18 小时前
【JavaScript性能优化实战】
开发语言·javascript·性能优化
罗不俷18 小时前
【Hadoop】Hadoop 起源与核心组件解析 —— 大数据时代的分布式基石
大数据·hadoop·分布式
inBuilder低代码平台20 小时前
Electron应用优化与性能调优策略
javascript·性能优化·electron
Moe4881 天前
CompletableFuture方法大全和使用详解(一步到位)
java·性能优化
陌上花开缓缓归以2 天前
linux系统移植过程中挂死问题分析
性能优化