0


【大数据Hive】hive 表数据优化使用详解

一、前言

通过之前的学习了解到,hive本身并不存储数据,其数据存储的本质还是HDFS,所有的数据读写都基于HDFS的文件来实现,因此对于hive表数据的优化可以归结为对hdfs上面存储数据相关的优化,比如数据存储格式的选择等。

二、hive 常用数据存储格式

为了提高对HDFS文件读写的性能,Hive提供了多种文件存储格式:TextFile、SequenceFile、ORC、Parquet等,不同的文件存储格式具有不同的存储特点,有的可以降低存储空间,有的可以提高查询性能。

Hive的文件格式在建表时指定,默认是TextFile,在hive的建表语法树中,在 [STORED AS file_format] 这一项中可以进行指定;

2.1 文件格式-TextFile

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

TextFile格式优缺点对比:
优点缺点应用场景
1、最简单的数据格式,可以直接查看

2、可以使用任意的分隔符进行分割

3、便于和其他工具共享数据

4、可以搭配压缩一起使用

1、耗费存储空间,I/O性能较低

2、结合压缩时Hive不进行数据切分合并,不能进行并行操作,查询效率低

3、按行存储,读取列的性能差

1、适合于小量数据的存储查询

2、一般用于做第一层数据加载和测试使用

2.1.1 操作演示

在本地有一个2K大小的文件

建表并加载数据

create table tb_sogou_source(
                                stime string,
                                userid string,
                                keyword string,
                                clickorder string,
                                url string
)
    row format delimited fields terminated by '\t';

load data local inpath '/usr/local/soft/data/sogo.reduced' into table tb_sogou_source;

执行过程

TextFile这种格式的文件的典型特征是,数据在hdfs上面文件大小与原文件保存不变,同时可以直接查看;

2.2 文件格式 - SequenceFile

SequenceFile是Hadoop里用来存储序列化的键值对即二进制的一种文件格式。SequenceFile文件也可以作为MapReduce作业的输入和输出,hive也支持这种格式。
优点缺点使用场景
1、以二进制的KV形式存储数据;

2、与底层交互更加友好,性能更快;

3、可压缩、可分割,优化磁盘利用率和I/O;

4、可并行操作数据,查询效率高;

5、也可以用于存储多个小文件

1、存储空间消耗最大;

2、与非Hadoop生态系统之外的工具不兼容;

3、构建SequenceFile需要通过TextFile文件转化加载
适合于小量数据,但是查询列比较多的场景
SequenceFile 底层存储架构图

2.2.1 操作演示

建表并加载数据

create table tb_sogou_seq(
                             stime string,
                             userid string,
                             keyword string,
                             clickorder string,
                             url string
)
    row format delimited fields terminated by '\t'
    stored as sequencefile;

insert into table tb_sogou_seq
select * from tb_sogou_source;

执行过程

从文件大小来说,略有减小,但是这种文件下载之后是二进制格式的;

2.3 文件格式 -Parquet

2.3.1 Parquet简介

  • Parquet是一种支持嵌套结构的列式存储文件格式,最早是由Twitter和Cloudera合作开发,2015年5月从Apache孵化器里毕业成为Apache顶级项目;
  • 是一种支持嵌套数据模型对的列式存储系统,作为大数据系统中OLAP查询的优化方案,它已经被多种查询引擎原生支持,并且部分高性能引擎将其作为默认的文件存储格式;
  • 通过数据编码和压缩,以及映射下推和谓词下推功能,Parquet的性能也较之其它文件格式有所提升;

优缺点对比
优点缺点使用场景
1、更高效的压缩和编码可压缩、可分割,优化磁盘利用率和I/O;

2、可用于多种数据处理框架
不支持update, insert, delete, ACID适用于字段数非常多,无更新,只取部分列的查询

2.3.2 操作演示

建表并加载数据

create table tb_sogou_parquet(
                                 stime string,
                                 userid string,
                                 keyword string,
                                 clickorder string,
                                 url string
)
    row format delimited fields terminated by '\t'
    stored as parquet;

insert into table tb_sogou_parquet
select * from tb_sogou_source;

执行过程

执行完成后,检查hdfs文件目录,对比原始文件可以看到这个压缩的比率还是很高的;

2.4 文件格式-ORC

2.4.1 ORC介绍

  • ORC(OptimizedRC File)文件格式也是一种Hadoop生态圈中的列式存储格式;
  • 它的产生早在2013年初,最初产生自Apache Hive,用于降低Hadoop数据存储空间和加速Hive查询速度;
  • 2015年ORC项目被Apache项目基金会提升为Apache顶级项目;
  • ORC不是一个单纯的列式存储格式,仍然是首先根据行组分割整个表,在每一个行组内进行按列存储;
  • ORC文件是自描述的,它的元数据使用Protocol Buffers序列化,并且文件中的数据尽可能的压缩以降低存储空间的消耗,目前也被Hive、Spark SQL、Presto等查询引擎支持;

优缺点:
优点缺点应用场景
1、列式存储,存储效率非常高;

2、可压缩,高效的列存取;

3、查询效率较高,支持索引;

4、支持矢量化查询

1、加载时性能消耗较大;

2、需要通过text文件转化生成;

3、读取全量数据时性能较差
适用于Hive中大型的存储、查询

2.4.2 操作演示

建表并加载数据

create table tb_sogou_orc(
                             stime string,
                             userid string,
                             keyword string,
                             clickorder string,
                             url string
)
    row format delimited fields terminated by '\t'
    stored as orc;

insert into table tb_sogou_orc
select * from tb_sogou_source;

执行过程

从hdfs文件目录下的数据来看,orc格式下文件仍然可以得到较大的压缩,使得存储空间大大降低;

三、hive 存储数据压缩优化

3.1 数据压缩-概述

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

Hive压缩实际上说的就是MapReduce的压缩。

下图是hive在运行MR任务时数据压缩过程的运行架构图

3.2 数据压缩的优缺点

3.2.1 压缩的优点

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

3.2.2 压缩的缺点

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

3.3 常用压缩格式和压缩算法

Hive中的压缩就是使用了Hadoop中的压缩实现的,所以Hadoop中支持的压缩在Hive中都可以直接使用。Hadoop中支持的压缩算法:

要想在Hive中使用压缩,需要对MapReduce和Hive进行相应的配置

3.3.1 Hadoop中各种压缩算法性能对比

3.3.2 压缩参数设置

--开启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;

3.3 操作演示

3.3.1 设置压缩参数

使用上面的压缩参数

3.3.2 创建表,指定为textfile格式

指定为textfile格式,并使用snappy压缩

drop table tb_sogou_snappy;

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

执行过程

3.3.3 创建表,指定为orc格式

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

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

执行过程

创建完成后,检查hdfs表的数据目录,可以发现数据目录的结尾会带有snappy,同时这个数据压缩比起上文更夸张了;

四、hive 存储优化

4.1 避免小文件生成

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;

4.2 ORC文件索引

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

4.2.1 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;

Row Group Index 补充说明

1、建立ORC格式表时,指定表参数’orc.create.index’=’true’之后,便会建立Row Group Index;

2、为了使Row Group Index有效利用,向表中加载数据时,必须对需要使用索引的字段进行排序;

4.2.2 核心参数设置

--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';

4.2.3 操作演示

开启索引配置

set hive.optimize.index.filter=true;

创建表并制定构建索引

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;

当进行范围或者等值查询(<,>,=)时就可以基于构建的索引进行查询

select count(*) from tb_sogou_orc_index where stime > '12:00:00' and stime < '18:00:00';

执行结果

4.2.4 Bloom Filter Index

俗称布隆过滤器索引

  • 建表时候通过表参数”orc.bloom.filter.columns”=”columnName……”来指定为哪些字段建立BloomFilter索引,在生成数据的时候,会在每个stripe中,为该字段建立BloomFilter的数据结构;
  • 当查询条件中包含对该字段的等值过滤时候,先从BloomFilter中获取以下是否包含该值,如果不包含,则跳过该stripe;

4.2.5 操作演示

创建表指定创建布隆索引

create table tb_sogou_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,userid的过滤可以走bloom filter index

select
    count(*)
from tb_sogou_orc_index
where stime > '12:00:00' and stime < '18:00:00'
  and userid = '3933365481995287' ;

执行结果

4.3 ORC矢量化查询

Hive的默认查询执行引擎一次处理一行,而矢量化查询执行是一种Hive针对ORC文件操作的特性,目的是按照每批1024行读取数据,并且一次性对整个记录整合(而不是对单条记录)应用操作,提升了像过滤, 联合, 聚合等等操作的性能。

注意:要使用矢量化查询执行,就必须以ORC格式存储数据。

开启矢量化查询参数

set hive.vectorized.execution.enabled = true;

set hive.vectorized.execution.reduce.enabled = true;

五、写在文末

本文通过大量案例详细探讨了Hive中表的常用优化策略,希望对看到的小伙伴有用哦,本篇到此结束,感谢观看。


本文转载自: https://blog.csdn.net/congge_study/article/details/129223657
版权归原作者 逆风飞翔的小叔 所有, 如有侵权,请联系我们删除。

“【大数据Hive】hive 表数据优化使用详解”的评论:

还没有评论