7.Hive性能优化及Hive3新特性

1.Hive表设计优化

  1. 分区表优化查询速度
  2. 分桶表优化join速度
  3. 索引优化(在Hive3后移除,了解即可)

2.Hive表数据优化

2.1 文件格式

概述

  • Hive数据存储的本质市HDFS,所有数据读写都基于HDFS的文件来实现
  • 为了提高对HDFS文件读写的性能,Hive提供了多种文件存储格式:TextFile、SequenceFile、ORC、Parguet等
  • 不同的文件存储格式具有不同的存储特点,有的可以降低存储空间,有的可以提高查询i性能
  • Hive的文件格式在建表时指定,默认时TextFile。指定语法:store as file_format

TextFile

  • TextFile时Hive中默认的文件格式,存储形式为按行存储
  • 工作中最常见的数据文件格式是TextFile文件,几乎所有的原始数据生成都是TextFile格式,所以Hive设计时考虑到为了避免各种编码及数据错乱的问题,选用了TextFile作为默认的格式
  • 建表时不指定存储格式即为TextFile,导入数据时把数据文件拷贝至HDFS不进行处理

优点:最简单的数据格式,可以直接查看
缺点:耗费存储空间,I/O性能较低

SequenceFile

  • SequenceFile是Hadoop里用来存储序列化的键值对即二进制的一种文件格式,通过insert+select生成
  • SequenceFile也可以作为MapReduce作业的输入和输出,Hive也支持这种格式

优点:以二进制的KV形式存储数据,与底层交互友好,性能更快
缺点:存储空间消耗最大

Parquet

  • Parquet是一种支持嵌套结构的列式存储文件格式。生成方式:insert+select
  • 是一种支持嵌套数据模型对的列式存储系统,作为大数据系统中OLAP查询的优化方案,它已经被多种拆线呢引擎原生支持,并且部分性能引擎将其作为默认的文件存储格式
  • 通过数据编码和压缩,以及映射下推和谓词下推等功能,Parquet的性能也较之其他文件格式有所提升

优点:更高效的压缩和编码可压缩、可分割,优化磁盘利用率和I/O,可用于多种数据处理框架
缺点:不支持update、insert、delete、ACID

ORC

  • ORC文件格式是一种Hadoop生态圈中的列式存储格式
  • 它的残生早在2013年初,最初产生自Apache Hive,用于降低Hadoop数据存储空间和加速Hive查询速度
  • ORC不是一个丹村的列式存储格式,人就时首先根据行组分割整个表,在每一行组内进行按列存储
  • ORC文件是自描述的,它的源数据使用Protocol Buffers序列化,并且文件中的数据尽可能的压缩以降低存储空间的消耗,目前也被Hive。Spark SQL、Presto等拆线呢引擎支持

优点:列式存储,存储效率高,可压缩,高效的列存取查询效率,支持索引,支持矢量化查询
缺点:加载时性能消耗较大,需要通过text文件转化生成读取全量数据时性能较差

2.2 数据压缩

概述

  • Hive底层运行MapReduce程序时,磁盘I/O操作、网络数据传输、shuffle和merge要花大量的时间,尤其是数据规模很大和工作负载密集的情况下
  • 鉴于磁盘I/O和网络宽带是Hadoop的宝贵资源,数据压缩对于节省资源、最小化磁盘I/O和网络传输非常有帮助
  • Hive压缩实际上说的就是MapReduce的压缩

压缩的优点
减少文件存储所占空间
加快文件传输效率,从而提高系统的处理速度
降低IO读写的次数

压缩的缺点
使用数据时需要先对文件解压,加重CPU负荷,压缩算法越复杂,解压时间越长

Hive中的压缩
Hive中的压缩就是使用了Hadoop中的压缩实现的,所以Hadoop中支持的压缩在Hive中都可以直接使用
Hadoop中支持的压缩算法:DEFLATE、gzip、bzip2、LZO、LZ4、Snappy
想要在Hive中使用压缩,需要对MapReduce和Hive进行相应的配置

Hive中压缩配置

-- 开启hive中间传输数据压缩功能
-- 1)开启hive中间传输数据压缩功能
set hive.exec.compress.insermediate=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中压缩测试
创建表,指定为textfile格式,并使用snappy压缩

create table tb_sogou_snappy
stored as textfile
as select * from tb_sogou_source;

创建表,指定为orc格式,并使用snappy压缩

create table tb_sogou_orc_snappy
stored as orc tblproperties ("orc.compress"="SNAPPY")
as select * from tb_sogou_source;

2.3 存储优化

避免小文件生成
Hive的存储本质时HDFS,HDFS时不利于小文件存储的,因为每个小文件会生成一条元数据信息,并且不利用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.ql.io.CombineHiveInputFormat;

ORC文件索引

  • 在使用ORC文件时,为了加快读取ORC文件中数据内容,ORC提供了两种索引机制:Row Group Index和Bloom Filter Index可以帮助提高查询ORC文件的性能
  • 当用户写入数据时,可以指定构建索引,当用户查询数据时,可以根据索引提前对数据进行过滤,避免不必要的数据扫描

Row Group Index

  • 一个ORC文件包含一个或多个stripes(groups of row data),每个stripe中包含了每个column的min/max值的索引数据
  • 当查询中有大于等于小于的操作时,会根据min/max值,跳过扫描不包含的stripes
  • 而其中为每个stripe建立的包含min/max值的索引,就成为Row Group Index行组索引,也叫min-max Index大小对比索引,或者Storage Index
  • 建立ORC格式表时,指定表参数’orc.create.index’='true’之后,便会建立Row Group Index
  • 为了使Row Group Index有效利用,向表中加载数据时,必须对需要使用索引的字段进行排序
-- 1.开启索引配置
set hive.optimize.index.filter=true
-- 2.创建表并指定构建索引
create table tb_sogou_orc_index
    stored as orc tblproperties("orc.create.index"="true")
as select * from tb_sogou_source
    distribute by stime
    sort by stime;
-- 3.当进行范围或者等职查询时就可以基于构建的索引进行查询
select count(*) from tb_sogou_orc_index where stime > '12:00:00' and stime < '18:00:00';

Bloom Filter Index

  • 建表时通过参数"orc.bloom.filter.columns"="columnName…"来指定为哪些字段建立BloomFilter索引,在生成数据的时候,会在每个stripe中,为该字段建立BloomFilter的数据结构
  • 当查询条件中包含对该字段的等值过滤时,先从BloomFilter中获取以下是否包含该值,如果不包含,则跳过该stripe
-- 创建表指定创建布隆索引
create table tb_sougou_orc_bloom
stored as orc tblproperties
("orc.create.index"="true","orc.bloom.filter.columns"="stime,userid")
as select * from tb_sogou_source
distribute by stime
sort by stime;

-- stime的范围过滤可以走row group index,userrid的过滤可以走bloom filter index
select count(*) from tb_sogou_orc_index
where stime > '12:00:00' and stime < '18:00:00'
and userid = '3933336519818919';

3.Hive Job任务执行优化

3.1 Explain查询计划

  • HQL时一种类SQL的语言,从变成语言规范来说是一种声明式语言,用户会根据查询需求提交生命的HQL查询,而Hive会根据底层计算引擎将其转化为Mapreduce/Tez/Spark的job
  • explain命令可以帮助用户了解一条HQL语言在底层的实现过程。通俗来说就是Hive打算如何去做这件事
  • explain会解析HQL语句,将整个HQL语句的实现步骤、依赖关系、实现过程都会进行解析返回,可以了解一条HQL语句在底层是如何实现数据的查询即处理的过程,附注用户对Hive进行优化

*常用语法命令

EXPLAIN [FORMATTED|EXTENDED|DEPENDENCY|AUTHORIZATION|] query

FORMATTED:对执行计划进行格式化,返回JSON格式的执行计划
EXTENDED:提供一些额外的i西南西,比如文件的路径信息
DEPENDENCY:以JSON格式返回查询所依赖的表和分区的列表
AUTHORIZATION:列出需要被授权的条目,包括输入于输出

每个查询计划由一下及部分组成:
1.抽象语法树(AST):Hive使用Antlr解析生成器,可以自动地将HQL生成抽象语法树
2.Stage依赖关系:会列出运行查询计划的stage阶段以及之间的依赖关系
3.stage内容:包含了每个stage非常重要的信息,比如运行时的operator和sort orders等具体信息

3.2 MapReduce属性优化

本地模式

  • 使用Hive的过程中,有一些数据量不大的表,也会转换为MapReduce处理,提交到集群时,需要申请资源,等待资源分配,启动JVM进程,再运行Task,一系列的过程比较繁琐,本身数据量并不大,提交到YARN运行返回会导致性能较差的问题
  • Hive为了解决这个问题,沿用了MapReduce中的设计,提供本地计算模式,允许程序不提交给YARN,直接在本地运行,以便提高小数据量程序的性能
-- 配置
-- 开启本地模式
set hive.exec.mode.local.auto = true;

提交任务满足以下三个条件(均可调)则使用本地模式:
输入大小小于128M
maptasks数小于4
reducetasks是0或1

JVM重用
1.Hadoop默认会为每个Task启动一个JVM来运行,而JVM启动时内存开销大
2.Job数量大的情况下,如果单个Task数据量较小,也会申请JVM,这就导致了资源紧张及浪费
3.JVM重用可以使得JVM实例在同一个job中重新使用N次,当一个Task运行结束以后,JVM不会进行解释,而是继续供下一个Task运行,直到运行N个Task以后,就会释放
4.N的值可以在Hadoop的mapred-site.xml文件中进行配置,通常在10-20之间

-- Hadoop3之前的配置在mapred-site.xml中添加以下参数
-- Hadoop3不再支持
mapreduce.job.jvm.numtasks=10

并行执行
Hive在实现HQL计算运行时,会解析为多个Stage,有时候Stage彼此之间有依赖关系,只能挨个执行,但是在一些别的场景下,很多Stage之间没有依赖关系。通过修改参数,开启并行执行,当多个stage之间没有依赖关系时,允许多个stage并行执行,提高性能

-- 开启stage并行化,默认为false
set hive.exec.parallel=true;
-- 指定并行化线程数,默认为8
set hive.exec.parallel.thread.number=16;

2.3 Join优化

  • Join时数据分析处理过程中必不可少的操作,Hive同样支持Join的语法
  • Hive Join的底层使用过MapReduce来实现的,Hive实现Join时,为了提高MapReduce的性能,提供了多种Join方案来实现
  • 例如适合小表Join大表的Map Join,大表Join大表的ReduceJoin,以及大表Join的优化方案Bucket Join等。

Map Join
原理:将小的那份数据给每个MapRask的内存都放一份完整的数据,大的数据每个部分都可以与小数据的完整数据进行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
原理:将两张表的数据在shuffle阶段利用shuffle的分组来将数据按照关联字段进行合并
必须经过shuffle,利用shuffle过程中的分组来实现关联
使用:Hive会自动判断是否满足Map Join,如果不满足Map Join则自动执行Reduce Join

Bucket Join
原理:将两张表按照想用的规则将数据划分,根据对应的规则对数据进行join,减少比较次数,提高性能
语法:clustered by colName
参数:set hive.optimize.bucketmapjoin=true;
要求:分桶字段=join字段,桶的个数相等或者成倍数

使用Sort Merge Bucket Join
基于有序的数据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字段=排序字段,桶个数相等或成倍数

2.4 优化器——关联优化

关联优化
当一个程序中如果某些操作彼此之间有关联性,可以开启关联优化,对有关联的操作进行解析时,尽量放在一个MapReduce中实现
配置:set hive.optimize.correlation=true;

2.5 优化器引擎

背景
Hive默认的优化器在解析一些聚合统计类的处理时,底层解析的方案有时候不是最佳方案

CBO优化器
RBO:基于规则的优化器,根据设定好的规则来对程序进行优化
CBO:基于代价的优化器,根据不同场景所需付出的代价来选择合适的优化方案
Hive中支持RBO与CBO两种引擎,默认时RBO

配置CBO

set hive.cbo.enable=true;
set hive.compute.query.using.stats=true;
set hive.stats.fetch.column.stats=true;

Analyze分析器
功能:用于提前运行一个MapReduce程序将表或分区的i西南西构建一些元数据,发配CBO引擎一起使用

语法

-- 构建分区信息元数据
ANALYZE TABLE tablename
[PARTITION(partcol1 [=val1], partcol2[=val2],...]
COMPUTE STATISTICS [noscan];

-- 构建列的元数据
ANALYZE TABLE tablename
[PARTITION(partcol1 [=val1], partcol2[=val2],...]
COMPUTE STATISTICS FOR COLUMNS (columns name1, columns name2...) [noscan];

-- 查看元数据
DESC FORMATTED [tablename] [columnname];
-- 分析优化器
-- 构建表中分区数据的元数据信息
analyze table tb_login_part partition(logindate) compute statistics;
-- 构建表中列的数据的元数据信息
analyze table tb_login_part compute statistics for columns userid;
-- 查看构建的列的元数据
desc formatted tb_login_part userid;

2.5 谓词下推(PPD)

谓词下推基本思想:将过滤表达式尽可能移动至靠近数据源的位置,以使真正执行时能直接跳过无关的数据。简单来说就是不影响最终结果的情况下,尽量将过滤条件提前执行

开启参数(默认开启):hive.optimize.ppd=true;

规则
1.对于join(inner join)、full outer join,条件写在 on后还是where后没有区别
2.对于left outer join,右侧的表写在on后,左侧的表写在where后,性能有提高
3.对于right outer join,左侧的表写在on后,右侧的表写在where后,性能有提高
4.当条件分散在两个表时,谓词下推可按照上述结论2和3自由组合

2.6 数据倾斜

数据倾斜就是当提交一个程序时,这个程序大多数的task都已经运行结束了,只有某个task一直在运行。
当程序运行group by或count(distinct)等分组聚合时,如果数据本身是倾斜的,根据MapReduce的Hash分区规则,一定会出现数据倾斜现象

解决方案
方案一:开启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左部分聚合操作,输出结果
第二个MapReduce将上一步聚合的结果按照业务进行处理,保证相同的分布到一起,最终聚合得到结果

数据倾斜Join
join操作时,如果两张表比较大,无法实现Map Join,只能走Reduce Join,那么当关联字段中某一种值过多时一九会导致数据倾斜的问题

方案一:提前过滤,将大数据变成小数据实现Map Join

方案二:使用Bucket Join
将两张表构建为分桶表

方案三:使用Skew Join
Skew Join时Hive中一种专门为了避免数据倾斜设计的特殊Join过程
这种Join的原理是将Map Join和Reduce Join进行合并,某个值出现数据倾斜,就会产生数据倾斜的数据单独使用Map Join来实现
其他没有产生数据倾斜的数据由Reduce Join来实现,这样就避免了Reduce Join中产生数据倾斜的问题
最终将Map Join的结果和Reduce Join的结果进行Union合并

使用Skew Join

-- 开启运行过程中Skejoin
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;

3.Hive3新特性

Hive从2.X版本开始就提示不推荐使用MR,未来的版本可能不能使用,推荐使用Tes或者Spark代替

3.1 Tez

Tez时Apache社区中一种支持DAG作业的开源计算框架
可以将多个有依赖的作业转换为一个作业从而答复提升DAG作业的性能,最终Tez也会将程序提交给YARN来实现运行
Tez并不直接面向最终用户,事实上它允许开发者为最终用户构建新歌能更快。扩展性更好的应用程序

3.2 LLAP更新

LLAP时hive2.0版本就引入的特性,在Hive3中与Tez继承的应用更加成熟
Hive光放称之为实时长期处理,实现将数据预取、缓存到基于yarn运行的守护进程中,降低和减少系统IO和与HDFS DataNode的交互,以极高程序性能,LLAP目前只支持Tez引擎
LLAP不会替代现有的执行模型,而是对其进行增强
LLAP守护程序是可选的
LLAP不是执行引擎
部分执行:LLAP程序执行的工作结果可以构建Hive查询结果的一部分
资源Management:YARn人就负责资源的管理和分配

3.3 Metastore独立模式

  • Hive中的所有对象如数据库、表、函数等。他们的定义都叫做metadata元数据
  • metastore时元数据存储服务,用于操作访问元数据
  • HIve或者其他执行引擎在运行时会使用这些元数据,来决定如何解析、授权和有效地执行用户拆线呢
  • metadata元数据可以存储配置为嵌入式的Apache Derby RDBMS或连接到外部RDBMS
  • Metastore本身完全嵌入到用户进程中,也可以作为服务运行,供其他进程连接

从Hive3.0开始,Metastore作为一个单独的包发布,可以在没有Hive其他部分的情况下运行。

猜你喜欢

转载自blog.csdn.net/hutc_Alan/article/details/131481195