简介: Hive 是大数据畛域罕用的组件之一,次要用于大数据离线数仓的运算,对于 Hive 的性能调优在日常工作和面试中是常常波及的一个点,因而把握一些 Hive 调优是必不可少的一项技能。影响 Hive 效率的次要因素有数据歪斜、数据冗余、job 的 IO 以及不同底层引擎配置状况和 Hive 自身参数和 HiveSQL 的执行等。本文次要从建表配置参数方面对 Hive 优化进行解说。
创立一个一般的表
create table test\_user1(id int, name string,code string,code\_id string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
查看表信息
DESCRIBE FORMATTED test\_user1;
咱们从该表的形容信息介绍建表时的一些可优化点。
2.1 表的文件数
numFiles 示意表中含有的文件数,当文件数过多时可能意味着该表的小文件过多,这时候咱们能够针对小文件的问题进行一些优化,HDFS 自身提供了
解决方案:
1.Hadoop Archive/HAR:将小文件打包成大文件。
2.SEQUENCEFILE 格局:将大量小文件压缩成一个 SEQUENCEFILE 文件。
3.CombineFileInputFormat:在 map 和 reduce 解决之前组合小文件。
4.HDFS Federation:HDFS 联盟,应用多个 namenode 节点管理文件。
除此之外,咱们还能够通过设置 hive 的参数来合并小文件。
1. 输出阶段合并
须要更改 Hive 的输出文件格式即参 hive.input.format
默认值是 org.apache.hadoop.hive.ql.io.HiveInputFormat 咱们改成org.apache.hadoop.hive.ql.io.CombineHiveInputFormat。
这样比起上面对 mapper 数的调整,会多出两个参数,别离是 mapred.min.split.size.per.node 和mapred.min.split.size.per.rack,含意是单节点和单机架上的最小 split 大小。如果发现有 split 大小小于这两个值(默认都是 100MB),则会进行合并。具体逻辑能够参看 Hive 源码中的对应类。
2. 输入阶段合并
间接将 hive.merge.mapfiles 和 hive.merge.mapredfiles 都设为 true 即可,前者示意将 map-only 工作的输入合并,后者示意将 map-reduce 工作的输入合并,Hive 会额定启动一个 mr 作业将输入的小文件合并成大文件。
另外,hive.merge.size.per.task 能够指定每个 task 输入后合并文件大小的期望值,hive.merge.size.smallfiles.avgsize 能够指定所有输入文件大小的均值阈值,默认值都是 1GB。如果均匀大小有余的话,就会另外启动一个工作来进行合并。
2.2 表的存储格局
通过 InputFormat 和 OutputFormat 能够看出表的存储格局是 TEXT 类型,Hive 反对 TEXTFILE, SEQUENCEFILE, AVRO, RCFILE, ORC, 以及 PARQUET 文件格式,能够通过两种形式指定表的文件格式:
1.CREATE TABLE … STORE AS <file_format>: 在建表时指定文件格式,默认是 TEXTFILE
2.ALTER TABLE … [PARTITION partition_spec] SET FILEFORMAT <file_format>: 批改具体表的文件格式。
如果要扭转创立表的默认文件格式,能够应用 set hive.default.fileformat=<file_format> 进行配置,实用于所有表。
同时也能够应用 set hive.default.fileformat.managed =<file_format> 进行配置,仅实用于外部表或内部表。
扩大:不同存储形式的状况
TEXT, SEQUENCE 和 AVRO 文件是面向行的文件存储格局,不是最佳的文件格式,因为即使只查问一列数据,应用这些存储格局的表也须要读取残缺的一行数据。另一方面,面向列的存储格局 (RCFILE, ORC, PARQUET) 能够很好地解决下面的问题。
对于每种文件格式的阐明,如下:
1.TEXTFILE
创立表时的默认文件格式,数据被存储成文本格式。文本文件能够被宰割和并行处理,也能够应用压缩,比方 GZip、LZO 或者 Snappy。然而大部分的压缩文件不反对宰割和并行处理,会造成一个作业只有一个 mapper 去解决数据,应用压缩的文本文件要确保文件不要过大,个别靠近两个 HDFS 块的大小。
2.SEQUENCEFILE
key/value 对的二进制存储格局,sequence 文件的劣势是比文本格式更好压缩,sequence 文件能够被压缩成块级别的记录,块级别的压缩是一个很好的压缩比例。如果应用块压缩,须要应用上面的配置:
set hive.exec.compress.output=true;
set io.seqfile.compression.type=BLOCK
3.AVRO
二进制格式文件,除此之外,avro 也是一个序列化和反序列化的框架。avro 提供了具体的数据 schema。
4.RCFILE
全称是 Record Columnar File,首先将表分为几个行组,对每个行组内的数据进行按列存储,每一列的数据都是离开存储,即先程度划分,再垂直划分。
5.ORC
全称是 Optimized Row Columnar,从 hive0.11 版本开始反对,ORC 格局是 RCFILE 格局的一种优化的格局,提供了更大的默认块(256M)
6.PARQUET
另外一种列式存储的文件格式,与 ORC 十分相似,与 ORC 相比,Parquet 格局反对的生态更广,比方低版本的 impala 不反对 ORC 格局。
配置同样数据同样字段的两张表,以常见的 TEXT 行存储和 ORC 列存储两种存储形式为例,比照执行速度。
TEXT 存储形式
ORC 存储形式
总结:
从上图中能够看出列存储在对指定列进行查问时,速度更快,倡议在建表时设置列存储的存储形式。
2.3 表的压缩
对 Hive 表进行压缩是常见的优化伎俩,一些存储形式自带压缩抉择,比方 SEQUENCEFILE 反对三种压缩抉择:NONE,RECORD,BLOCK。Record 压缩率低,个别倡议应用 BLOCK 压缩。
ORC 反对三种压缩抉择:NONE,ZLIB,SNAPPY。咱们以 TEXT 存储形式和 ORC 存储形式为例,查看表的压缩状况。
配置同样数据同样字段的四张表,一张 TEXT 存储形式,另外三张别离是默认压缩形式的 ORC 存储、SNAPPY 压缩形式的 ORC 存储和 NONE 压缩形式的 ORC 存储,查看在 hdfs 上的存储状况:
TEXT 存储形式
默认压缩 ORC 存储形式
SNAPPY 压缩的 ORC 存储形式
NONE 压缩的 ORC 存储形式
总结:
能够看到 ORC 存储形式将数据寄存为两个 block,默认压缩大小加起来 134.69M,SNAPPY 压缩大小加起来 196.67M,NONE 压缩大小加起来 247.55M。
TEXT 存储形式的文件大小为 366.58M,且默认 block 两种存储形式别离为 256M 和 128M。
ORC 默认的压缩形式比 SNAPPY 压缩失去的文件还小,起因是 ORZ 默认的 ZLIB 压缩形式采纳的是 deflate 压缩算法,比 Snappy 压缩算法失去的压缩比高,压缩的文件更小。
ORC 不同压缩形式之间的执行速度,通过屡次测试发现三种压缩形式的执行速度差不多,所以倡议采纳 ORC 默认的存储形式进行存储数据。
2.4 分桶分区
Num Buckets 示意桶的数量,咱们能够通过分桶和分区操作对 Hive 表进行优化。
对于一张较大的表,能够将它设计成分区表,如果不设置成分区表,数据是全盘扫描的,设置成分区表后,查问时只在指定的分区中进行数据扫描,晋升查问效率。要留神尽量避免多级分区,个别二级分区足够应用。常见的分区字段:
1. 日期或者工夫,比方 year、month、day 或者 hour,当表中存在工夫或者日期字段时,能够应用些字段。
2. 地理位置,比方国家、省份、城市等。
3. 业务逻辑,比方部门、销售区域、客户等等。
与分区表相似,分桶表的组织形式是将 HDFS 上的一张大表文件宰割成多个文件。
分桶是绝对分区进行更细粒度的划分,分桶将整个数据内容依照分桶字段属性值得 hash 值进行辨别,分桶能够放慢数据采样,也能够晋升 join 的性能(join 的字段是分桶字段),因为分桶能够确保某个 key 对应的数据在一个特定的桶内(文件),所以奇妙地抉择分桶字段能够大幅度晋升 join 的性能。
通常状况下,分桶字段能够抉择常常用在过滤操作或者 join 操作的字段。
创立分桶表
createtabletest\_user\_bucket(idint,namestring,codestring,code\_idstring) clusteredby(id)into3bucketsROWFORMATDELIMITEDFIELDSTERMINATEDBY',';
查看形容信息
DESCRIBEFORMATTED test\_user\_bucket
多出了如下信息
查看该表的 hdfs
同样的数据查看一般表和分桶表查问效率
一般表
分桶表
一般表是全表扫描,分桶表在依照分桶字段的 hash 值分桶后,依据 join 字段或者 where 过滤字段在特定的桶中进行扫描,效率晋升。
本次优化次要建表配置参数方面对 Hive 优化进行解说,这是 Hive 优化的第一步,正如大多数据库一样,残缺的调优必然还包含模型设计、引擎调优,对于这部分的内容请关注后续连载。